Skip to content

Add support for Ruby 2.7#1692

Merged
wsfulton merged 3 commits intoswig:masterfrom
treitmayr:ruby2.7-support
Jan 5, 2020
Merged

Add support for Ruby 2.7#1692
wsfulton merged 3 commits intoswig:masterfrom
treitmayr:ruby2.7-support

Conversation

@treitmayr
Copy link
Contributor

This commit fixes the signatures of various callback methods
based on https://github.com/ruby/ruby/pull/2404/files?file-filters%5B%5D=.h
and cleans up the macro definitions used for casting callbacks.

Note that the transparent version of the macro RUBY_METHOD_FUNC
is currently masked behind RUBY_DEVEL, see commit
ruby/ruby@1d91fea
In order to still support strict signature checking and prevent
nasty deprecation warnings, the use of RUBY_METHOD_FUNC had to
be replaced with VALUEFUNC.

This commit also fixes issue #1689.

@anatol
Copy link
Contributor

anatol commented Dec 30, 2019

Thank you very much for the patch. I backported it to SWIG3 (used by libsigrok due to https://sigrok.org/bugzilla/show_bug.cgi?id=1468) and was able to compile libsigrok. There are few warnings that you might be interested in

bindings/ruby/classes_wrap.cpp: In function ‘std::map<std::__cxx11::basic_string<char>, Glib::VariantBase> hash_to_map_options(VALUE, std::map<std::__cxx11::basic_string<char>, std::shared_ptr<sigrok::Option> >)’:
bindings/ruby/classes_wrap.cpp:10582:75: warning: ‘void ruby::backward::cxxanyargs::rb_hash_foreach(VALUE, int (*)(...), VALUE)’ is deprecated: Use of ANYARGS in this function is deprecated [-Wdeprecated-declarations]
10582 |     rb_hash_foreach(hash, (int (*)(ANYARGS))convert_option, (VALUE)&params);
      |                                                                           ^
In file included from /usr/include/ruby-2.7.0/ruby/ruby.h:2863,
                 from /usr/include/ruby-2.7.0/ruby.h:33,
                 from bindings/ruby/classes_wrap.cpp:879:
/usr/include/ruby-2.7.0/ruby/backward/cxxanyargs.hpp:412:1: note: declared here
  412 | rb_hash_foreach(VALUE q, int_type *w, VALUE e)
      | ^~~~~~~~~~~~~~~
bindings/ruby/classes_wrap.cpp:10582:75: warning: ‘void ruby::backward::cxxanyargs::rb_hash_foreach(VALUE, int (*)(...), VALUE)’ is deprecated: Use of ANYARGS in this function is deprecated [-Wdeprecated-declarations]
10582 |     rb_hash_foreach(hash, (int (*)(ANYARGS))convert_option, (VALUE)&params);
      |                                                                           ^
In file included from /usr/include/ruby-2.7.0/ruby/ruby.h:2863,
                 from /usr/include/ruby-2.7.0/ruby.h:33,
                 from bindings/ruby/classes_wrap.cpp:879:
/usr/include/ruby-2.7.0/ruby/backward/cxxanyargs.hpp:412:1: note: declared here
  412 | rb_hash_foreach(VALUE q, int_type *w, VALUE e)
      | ^~~~~~~~~~~~~~~
bindings/ruby/classes_wrap.cpp: In function ‘std::vector<std::shared_ptr<sigrok::HardwareDevice> > sigrok_Driver__scan__SWIG_0(sigrok::Driver*, VALUE)’:
bindings/ruby/classes_wrap.cpp:10854:89: warning: ‘void ruby::backward::cxxanyargs::rb_hash_foreach(VALUE, int (*)(...), VALUE)’ is deprecated: Use of ANYARGS in this function is deprecated [-Wdeprecated-declarations]
10854 |         rb_hash_foreach(kwargs, (int (*)(ANYARGS))convert_option_by_key, (VALUE)&options);
      |                                                                                         ^
In file included from /usr/include/ruby-2.7.0/ruby/ruby.h:2863,
                 from /usr/include/ruby-2.7.0/ruby.h:33,
                 from bindings/ruby/classes_wrap.cpp:879:
/usr/include/ruby-2.7.0/ruby/backward/cxxanyargs.hpp:412:1: note: declared here
  412 | rb_hash_foreach(VALUE q, int_type *w, VALUE e)
      | ^~~~~~~~~~~~~~~
bindings/ruby/classes_wrap.cpp:10854:89: warning: ‘void ruby::backward::cxxanyargs::rb_hash_foreach(VALUE, int (*)(...), VALUE)’ is deprecated: Use of ANYARGS in this function is deprecated [-Wdeprecated-declarations]
10854 |         rb_hash_foreach(kwargs, (int (*)(ANYARGS))convert_option_by_key, (VALUE)&options);
      |                                                                                         ^
In file included from /usr/include/ruby-2.7.0/ruby/ruby.h:2863,
                 from /usr/include/ruby-2.7.0/ruby.h:33,
                 from bindings/ruby/classes_wrap.cpp:879:
/usr/include/ruby-2.7.0/ruby/backward/cxxanyargs.hpp:412:1: note: declared here
  412 | rb_hash_foreach(VALUE q, int_type *w, VALUE e)
      | ^~~~~~~~~~~~~~~
  CXXLD    bindings/cxx/libsigrokcxx.la
ar: `u' modifier ignored since `D' is the default (see `U')
  GEN      bindings/java/libsigrok_java_core_classes.so
  GEN      bindings/python/timestamp
sigrok/core/classes_wrap.cpp:1844:36: warning: cast between incompatible function types from ‘PyObject* (*)(PyObject*)’ {aka ‘_object* (*)(_object*)’} to ‘PyCFunction’ {aka ‘_object* (*)(_object*, _object*)’} [-Wcast-function-type]
 1844 |   {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
      |                                    ^~~~~~~~~~~~~~~~~~~
sigrok/core/classes_wrap.cpp:1845:36: warning: cast between incompatible function types from ‘PyObject* (*)(PyObject*)’ {aka ‘_object* (*)(_object*)’} to ‘PyCFunction’ {aka ‘_object* (*)(_object*, _object*)’} [-Wcast-function-type]
 1845 |   {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
      |                                    ^~~~~~~~~~~~~~~~~~~~
sigrok/core/classes_wrap.cpp:1848:36: warning: cast between incompatible function types from ‘PyObject* (*)(PyObject*)’ {aka ‘_object* (*)(_object*)’} to ‘PyCFunction’ {aka ‘_object* (*)(_object*, _object*)’} [-Wcast-function-type]
 1848 |   {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
      |                                    ^~~~~~~~~~~~~~~~~
sigrok/core/classes_wrap.cpp:1849:36: warning: cast between incompatible function types from ‘PyObject* (*)(SwigPyObject*)’ {aka ‘_object* (*)(SwigPyObject*)’} to ‘PyCFunction’ {aka ‘_object* (*)(_object*, _object*)’} [-Wcast-function-type]
 1849 |   {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
      |                                    ^~~~~~~~~~~~~~~~~
sigrok/core/classes_wrap.cpp: In function ‘PyTypeObject* SwigPyObject_TypeOnce()’:
sigrok/core/classes_wrap.cpp:2007:5: warning: missing initializer for member ‘_typeobject::tp_vectorcall’ [-Wmissing-field-initializers]
 2007 |     };
      |     ^
sigrok/core/classes_wrap.cpp:2007:5: warning: missing initializer for member ‘_typeobject::tp_print’ [-Wmissing-field-initializers]
sigrok/core/classes_wrap.cpp: In function ‘PyTypeObject* SwigPyPacked_TypeOnce()’:
sigrok/core/classes_wrap.cpp:2194:5: warning: missing initializer for member ‘_typeobject::tp_vectorcall’ [-Wmissing-field-initializers]
 2194 |     };
      |     ^
sigrok/core/classes_wrap.cpp:2194:5: warning: missing initializer for member ‘_typeobject::tp_print’ [-Wmissing-field-initializers]
  CXXLD    bindings/ruby/sigrok.so
sigrok/core/classes_wrap.cpp: In function ‘PyTypeObject* swig_varlink_type()’:
sigrok/core/classes_wrap.cpp:61564:7: warning: missing initializer for member ‘_typeobject::tp_vectorcall’ [-Wmissing-field-initializers]
61564 |       };
      |       ^

@treitmayr
Copy link
Contributor Author

The deprecation warnings regarding rb_hash_foreach result from code in your classes.i file. There you need to specify the second argument as INT_ANYARGS_FUNC(convert_option) instead of (int (*)(ANYARGS))convert_option and the warning should be fixed. The same applies to convert_option_by_key.
The remaining warnings have nothing to do with the Ruby version, right?

@treitmayr
Copy link
Contributor Author

Is there a way to find out when a certain Ruby version is supported by rvm in the Travis CI? Or shall I remove the new entry in .travis.yml for now?

Comment on lines +303 to +307
- compiler: gcc
os: linux
env: SWIGLANG=ruby VER=2.7.0
sudo: required
dist: xenial
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added in ruby-2.7 testing on Travis to master in 5259082. Can you please remove the changes to .travis.yml and push an updated patch? Then we can then see how your patch performs using 2.7.0p0 on Travis. Thanks.

Copy link
Contributor Author

@treitmayr treitmayr Dec 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually Travis ran its tests just fine 3 hours ago with my newly committed change (where "2.7.0" instead of "2.7" is requested), see https://travis-ci.org/swig/swig/jobs/631045861?utm_medium=notification&utm_source=github_status .

Sorry for not stating this good news already. How shall we proceed now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one, I don't know how you found that was supported as rvm list known doesn't include 2.7.0p0, just 2.7[.0-preview1]. Anyway, either approach tests what we want which is good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a gut feeling that there might be some fallback for fully specified version strings. However the final patch does not include that one in favor of your more elaborate solution and to resolve the conflicts.

This commit fixes the signatures of various callback methods
and cleans up the macro definitions used for casting callbacks.

Note that the transparent version of the macro RUBY_METHOD_FUNC
is currently masked behind RUBY_DEVEL, see commit
ruby/ruby@1d91fea
In order to still support strict signature checking and prevent
nasty deprecation warnings, the use of RUBY_METHOD_FUNC had to
be replaced with VALUEFUNC.
@treitmayr
Copy link
Contributor Author

treitmayr commented Dec 31, 2019

Now I also adapted the code for Ruby global variables for Ruby 2.7 (and it actually became shorter and hopefully easier to read), and fixed the excessive white spaces in the macro definitions (therefore the second push).
If the CI build has passed (some time next year) then this will be my new proposal.

@wsfulton
Copy link
Member

wsfulton commented Jan 3, 2020

I know the existing macros PROTECTFUNC VALUEFUNC VOIDFUNC are polluting the global namespace, but the new ones VOID_ANYARGS_FUNC and INT_ANYARGS_FUNC ought to be prefixed with SWIG_RUBY_ so as to not pollute the global namespace. I don't know the history of the existing macro names, but we can't change them now as this will go into a patch release of SWIG, but we could rename them at a later date.

@treitmayr
Copy link
Contributor Author

Ok, makes sense, I will change it.
(BTW, I guess in order to have a clean history I will rewrite the original commit instead of adding one!? Just to make sure I comply to this project's rules...)

@wsfulton
Copy link
Member

wsfulton commented Jan 3, 2020

It really doesn't matter in this case.

@@ -110,26 +110,18 @@
* can be passed as an argument to API functions like Data_Wrap_Struct()
* and Data_Make_Struct().
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above needs updating. I think the 1st two lines should be replaced with something like:

The following macros are for backwards compatibility and using strictly correct function signatures in C++
when Ruby 2.7 removed ANYARGS and replaced callback function signatures with explicit types.

Is this your understanding as well? Feel free to reword.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I missed that, but I will have to postpone the change until tomorrow...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it, and learned something about "function declarators with empty parentheses" (https://stackoverflow.com/a/20835620) used in the Ruby C API for C (not C++) extensively before version 2.7. That's why there is this additional condition regarding C++ in the macro definition block.

The macros for casting function pointers are now fully described and also
clarify why the macros act transparently for C even before Ruby 2.7.

In addition, an "if (CPlusPlus)" was removed in the code generator for
global variables in order to keep the distinction between C and C++ in
one place, which is at the definition of said macros.
@wsfulton wsfulton added the Ruby label Jan 5, 2020
@wsfulton wsfulton merged commit f5908ec into swig:master Jan 5, 2020
chezou added a commit to chezou/Mykytea-ruby that referenced this pull request Mar 1, 2020
Because swig 4.0.1 doesn't support Ruby 2.7 yet, stop testing Ruby
2.7.

See also: swig/swig#1692
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants