alpinweis / cronex

Ruby library that converts cron expressions into human readable strings
Other
78 stars 29 forks source link

Unicode dependency compilation issues #32

Closed edwardloveall closed 4 months ago

edwardloveall commented 7 months ago

Hello! When installing this gem on ruby 3.3 I get an error when it tries to install the unicode dependency:

In Gemfile:
  cronex was resolved to 0.13.0, which depends on
    unicode

and a lot of text like:

unicode.c:37:7: warning: 'RB_OBJ_TAINTED' is deprecated: taintedness turned out to be a wrong idea. [-Wdeprecated-declarations]
  if (OBJ_TAINTED(src))

Obviously, this is not cronex, but because cronex uses unicode to handle case transformation it breaks. Luckily, someone is already working on a fix: https://github.com/blackwinter/unicode/pull/11

I also wonder if this gem needs the unicode dependency. I made the following change to the transform_case method and all the tests still passed:

def transform_case(desc, case_type = :lower)
  case case_type
  when :sentence
-   desc.sub(/\b[[:word:]]/u) { |s| Unicode.upcase(s) }
+   desc.sub(/\b[[:word:]]/u) { |s| s.upcase }
  when :title
-   desc.gsub(/\b[[:word:]]/u) { |s| Unicode.upcase(s) }
+   desc.gsub(/\b[[:word:]]/u) { |s| s.upcase }
  else
-   Unicode.downcase(desc)
+   desc.downcase
  end
end

Although I'm not sure the tests are exhaustive here and I understand unicode can be complex. I'm totally open to the idea that this is not an adequate fix.

noizwaves commented 7 months ago

I'm seeing similar errors when trying to install cronex 0.11.1 and unicode:

Installing unicode 0.4.4.4 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
...
unicode.c:1039:20: error: incompatible function pointer types passing 'VALUE (get_categories_param *)' (aka 'unsigned long (struct _get_categories_param *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned
long)') [-Wincompatible-function-pointer-types]
  return rb_ensure(get_categories_internal, (VALUE)&param,
                   ^~~~~~~~~~~~~~~~~~~~~~~
/Users/adam.neumann/.rbenv/versions/3.3.0/include/ruby-3.3.0/ruby/internal/iterator.h:425:25: note: passing argument to parameter 'b_proc' here
VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);
                        ^
unicode.c:1040:20: error: incompatible function pointer types passing 'VALUE (WString *)' (aka 'unsigned long (struct _WString *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)')
[-Wincompatible-function-pointer-types]
                   get_categories_ensure, (VALUE)&wstr);
                   ^~~~~~~~~~~~~~~~~~~~~
/Users/adam.neumann/.rbenv/versions/3.3.0/include/ruby-3.3.0/ruby/internal/iterator.h:425:62: note: passing argument to parameter 'e_proc' here
VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);
                                                             ^
...
unicode.c:1057:20: error: incompatible function pointer types passing 'VALUE (get_categories_param *)' (aka 'unsigned long (struct _get_categories_param *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned
  long)') [-Wincompatible-function-pointer-types]
    return rb_ensure(get_categories_internal, (VALUE)&param,
                     ^~~~~~~~~~~~~~~~~~~~~~~
  /Users/adam.neumann/.rbenv/versions/3.3.0/include/ruby-3.3.0/ruby/internal/iterator.h:425:25: note: passing argument to parameter 'b_proc' here
  VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);
                          ^
  unicode.c:1058:20: error: incompatible function pointer types passing 'VALUE (WString *)' (aka 'unsigned long (struct _WString *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)')
  [-Wincompatible-function-pointer-types]
                     get_categories_ensure, (VALUE)&wstr);
                     ^~~~~~~~~~~~~~~~~~~~~
...
unicode.c:1227:20: error: incompatible function pointer types passing 'VALUE (get_text_elements_param *)' (aka 'unsigned long (struct _get_text_elements_param *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long
(*)(unsigned long)') [-Wincompatible-function-pointer-types]
  return rb_ensure(get_text_elements_internal, (VALUE)&param,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/adam.neumann/.rbenv/versions/3.3.0/include/ruby-3.3.0/ruby/internal/iterator.h:425:25: note: passing argument to parameter 'b_proc' here
VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2);
                        ^
unicode.c:1228:20: error: incompatible function pointer types passing 'VALUE (WString *)' (aka 'unsigned long (struct _WString *)') to parameter of type 'VALUE (*)(VALUE)' (aka 'unsigned long (*)(unsigned long)')
[-Wincompatible-function-pointer-types]
                   get_text_elements_ensure, (VALUE)&wstr);
                   ^~~~~~~~~~~~~~~~~~~~~~~~
...
20 warnings and 6 errors generated.
make: *** [unicode.o] Error 1

make failed, exit code 2
alpinweis commented 7 months ago

Case conversion (as done by upcase) is complicated and locale-dependent. So Unicode was chosen in this gem to do this job as the goal was to support any language. The fact that the currently supported languages in cronex don't seem to require Unicode.upcase vs the regular string.upcase does not mean this may be true for other languages someone might want to add support for. So I'd rather wait for a Unicode fix than fall back tostring.upcase.

anthonysapien commented 7 months ago

@alpinweis if you can please review this thread, it looks like the original maintainer of the unicode gem has disappeared, and now there's only a "temporary maintainer" that has put a fix into a separate fork. https://github.com/blackwinter/unicode/pull/11

I'm not sure we'll see an imminent patch to blackwinter's repository.

alpinweis commented 7 months ago

I'm on Apple M2 Pro, Sonoma 14.4, ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]. I can reproduce it when I run bundle install or gem install unicode.

I followed the solution suggested at https://stackoverflow.com/questions/78129921/gemextbuilderror-error-failed-to-build-gem-native-extension-unicode-c1058 and it fixed it for me.

Option 1:

bundle config build.unicode --with-cflags="-Wno-incompatible-function-pointer-types" 
bundle install

Option 2:

gem install unicode -- --with-cflags="-Wno-incompatible-function-pointer-types"
bundle install
alpinweis commented 4 months ago

The issue is fixed in unicode (0.4.4.5)