Project

General

Profile

Actions

Bug #17777

closed

2.6.7 fails to build on macOS: implicit declaration of function 'rb_native_mutex_destroy' is invalid in C99

Added by Eregon (Benoit Daloze) 5 months ago. Updated 4 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:103241]

Description

https://github.com/ruby/ruby-builder/runs/2271346109?check_suite_focus=true#step:14:11253

vm.c:2295:9: error: implicit declaration of function 'rb_native_mutex_destroy' is invalid in C99 

There is also a warning below that might be worth solving:

vm.c:2489:34: warning: expression does not compute the number of elements in this array; element type is 'const int', not 'VALUE' (aka 'unsigned long') [-Wsizeof-array-div]
                             sizeof(ec->machine.regs) / sizeof(VALUE));
                                    ~~~~~~~~~~~~~~~~  ^
vm.c:2489:34: note: place parentheses around the 'sizeof(VALUE)' expression to silence this warning

Updated by chrisseaton (Chris Seaton) 5 months ago

I've also been experiencing this build failure and can reproduce on multiple systems.

Updated by Eregon (Benoit Daloze) 5 months ago

A workaround is export warnflags=-Wno-error=implicit-function-declaration and then attempt to build/install 2.6.7 again.

That downgrades the error to a warning, but relying on implicit function declaration seems potentially dangerous as the argument types are unknown.

Actions #3

Updated by usa (Usaku NAKAMURA) 5 months ago

  • Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.6: REQUIRED, 2.7: DONTNEED, 3.0: DONTNEED

Updated by usa (Usaku NAKAMURA) 5 months ago

In principal, we will not change ruby_2_6 no longer except security issue.
But this is a severe build problem, therefore I'll patch for it exceptionally, if a patch verified by macOS user will be provided :)

Updated by udzura (Uchio KONDO) 5 months ago

Hi,

Using MacOS 10.15.7 / Apple clang version 11.0.3 (clang-1103.0.32.62), building ruby 2.6.7 will be sccessful.

Using MacOS 10.15.7 / Apple clang version 12.0.0 (clang-1200.0.32.28), it is broken (reported by ima1zumi (Mari Imaizumi)).

I hope this will be of some help.

Updated by xtkoba (Tee KOBAYASHI) 5 months ago

I believe this issue was introduced by #15852#note-9 (backport of 2a83650b0fd25719fb6c03bfec7bd895734d3ceb into ruby_2_6).

A workaround is to define a prototype of the function rb_native_mutex_destroy before it is called, as in the following patch:

--- ruby-2.6.7/vm.c.orig
+++ ruby-2.6.7/vm.c
@@ -2292,6 +2292,7 @@ ruby_vm_destruct(rb_vm_t *vm)
    if (objspace) {
        rb_objspace_free(objspace);
    }
+        void rb_native_mutex_destroy(rb_nativethread_lock_t *);
         rb_native_mutex_destroy(&vm->waitpid_lock);
         rb_native_mutex_destroy(&vm->workqueue_lock);
    /* after freeing objspace, you *can't* use ruby_xfree() */

Updated by austin (Austin Ziegler) 5 months ago

Copying the include/ruby/thread_native.h from master appears to work to a point. This is what I found: git show 5e3259ea749 -- include/ruby/thread_native.h.

5e3259ea74 2020-11-17 | fix public interface [Koichi Sasada]

diff --git a/include/ruby/thread_native.h b/include/ruby/thread_native.h
index 0285c8ff40..7e08c2e97f 100644
--- a/include/ruby/thread_native.h
+++ b/include/ruby/thread_native.h
@@ -31,10 +31,14 @@ typedef union rb_thread_lock_union {
     CRITICAL_SECTION crit;
 } rb_nativethread_lock_t;

+typedef struct rb_thread_cond_struct rb_nativethread_cond_t;
+
 #elif defined(HAVE_PTHREAD_H)
+
 #include <pthread.h>
 typedef pthread_t rb_nativethread_id_t;
 typedef pthread_mutex_t rb_nativethread_lock_t;
+typedef pthread_cond_t rb_nativethread_cond_t;

 #else
 #error "unsupported thread type"
@@ -50,6 +54,19 @@ void rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);
 void rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);
 void rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);

+void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
+int  rb_native_mutex_trylock(rb_nativethread_lock_t *lock);
+void rb_native_mutex_unlock(rb_nativethread_lock_t *lock);
+void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
+void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
+
+void rb_native_cond_signal(rb_nativethread_cond_t *cond);
+void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
+void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
+void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec);
+void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
+void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
+
 RUBY_SYMBOL_EXPORT_END

 #endif

However, when building ext/fiddle, I get the following error:

closure.c:264:14: error: implicit declaration of function 'ffi_prep_closure' is invalid in C99
      [-Werror,-Wimplicit-function-declaration]
    result = ffi_prep_closure(pcl, cif, callback, (void *)self);

I’m not sure why this is failing here, because it doesn’t look like it’s implicit (the function ffi_prep_closure is in ffi.h which is included from fiddle.h, which is included in closure.c.

Updated by austin (Austin Ziegler) 5 months ago

Digging a bit deeper in to this second item; it looks like we’re doing USE_HEADER_HACKS, which means we’re loading <ffi/ffi.h> and using the compiler that came with Big Sur (based on Xcode 12), I see the following:

#if FFI_LEGACY_CLOSURE_API
FFI_AVAILABLE_APPLE_2019 FFI_API ffi_status
ffi_prep_closure (ffi_closure*,
          ffi_cif *,
          void (*fun)(ffi_cif*,void*,void**,void*),
          void *user_data)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
  __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
#elif defined(__GNUC__) && __GNUC__ >= 3
  __attribute__((deprecated))
#endif
  ;
#endif

However, it looks like the 2.7 version of fiddle does a little more investigation:

--- ext/fiddle/extconf.rb   2021-04-05 07:48:34.000000000 -0400
+++ ../ruby-2.7.3/ext/fiddle/extconf.rb 2021-04-05 08:39:38.000000000 -0400
@@ -13,7 +13,7 @@
   if have_header(ffi_header = 'ffi.h')
     true
   elsif have_header(ffi_header = 'ffi/ffi.h')
-    $defs.push(format('-DUSE_HEADER_HACKS'))
+    $defs.push('-DUSE_HEADER_HACKS')
     true
   end and (have_library('ffi') || have_library('libffi'))
 end or
@@ -114,8 +114,17 @@

 if ver
   ver = ver.gsub(/-rc\d+/, '') # If ver contains rc version, just ignored.
-  ver = (ver.split('.') + [0,0])[0,3]
+  ver = (ver.split('.').map(&:to_i) + [0,0])[0,3]
   $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % ver }})
+  warn "libffi_version: #{ver.join('.')}"
+end
+
+case
+when $mswin, $mingw, (ver && (ver <=> [3, 2]) >= 0)
+  $defs << "-DUSE_FFI_CLOSURE_ALLOC=1"
+when (ver && (ver <=> [3, 2]) < 0)
+else
+  have_func('ffi_closure_alloc', ffi_header)
 end

 have_header 'sys/mman.h'
@@ -142,7 +151,7 @@
   if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config
     if size = $2 and size != 'VOIDP'
       size = types.fetch(size) {size}
-      $defs << format("-DTYPE_%s=TYPE_%s", signed||type, size)
+      $defs << "-DTYPE_#{signed||type}=TYPE_#{size}"
     end
     if signed
       check_signedness(type.downcase, "stddef.h")

This is from 229c041f057.

Updated by austin (Austin Ziegler) 5 months ago

Copying the ext/fiddle/extconf.rb from 229c041f057 also seems to work.

Actions #12

Updated by jeremyevans0 (Jeremy Evans) 5 months ago

  • Status changed from Open to Closed

Updated by tlbra (tycho braams) 5 months ago

I think it's a bit early to close the issue, as the PR linked by hsbt has not actually been merged in the 2.6 branch yet, so the issue still exists

Updated by jeremyevans0 (Jeremy Evans) 5 months ago

tlbra (tycho braams) wrote in #note-13:

I think it's a bit early to close the issue, as the PR linked by hsbt has not actually been merged in the 2.6 branch yet, so the issue still exists

You must be unfamiliar with how backporting is handled in Ruby. If the issue doesn't exist in the master branch but needs backporting, the issue is closed and the appropriate backport flag is set. The branch maintainer will use a view like https://bugs.ruby-lang.org/projects/ruby-master/issues?query_id=171 to determine which tickets need backporting (note that it includes issues marked Closed, including this ticket).

Updated by tlbra (tycho braams) 5 months ago

Yep, I was not aware that that is how it works, thank you for explaining the process.

Updated by tdehnke (Tony Dehnke) 5 months ago

Newbie here, I just ran into this today on my Mac running MacOS 11.2.3 (Intel)

Based on the above it sounds like we would need to wait for 2.6.8 to update Ruby safely?

tdehnke@Tonys-MacBook-Pro-15 12vBiz % rbenv install 2.6.7
Downloading ruby-2.6.7.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.7.tar.bz2
Installing ruby-2.6.7...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 11.2.3 using ruby-build 20210420)

Inspect or clean up the working tree at /var/folders/r0/vw984xf56318dq54dzjk26wm0000gn/T/ruby-build.20210421115228.39383.OiFuid
Results logged to /var/folders/r0/vw984xf56318dq54dzjk26wm0000gn/T/ruby-build.20210421115228.39383.log

Last 10 log lines:
vm.c:2295:9: error: implicit declaration of function 'rb_native_mutex_destroy' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        rb_native_mutex_destroy(&vm->waitpid_lock);
        ^
vm.c:2489:34: warning: expression does not compute the number of elements in this array; element type is 'const int', not 'VALUE' (aka 'unsigned long') [-Wsizeof-array-div]
                             sizeof(ec->machine.regs) / sizeof(VALUE));
                                    ~~~~~~~~~~~~~~~~  ^
vm.c:2489:34: note: place parentheses around the 'sizeof(VALUE)' expression to silence this warning
1 warning and 1 error generated.
make: *** [vm.o] Error 1
make: *** Waiting for unfinished jobs....

Updated by austin (Austin Ziegler) 5 months ago

This hasn’t yet been backported. When it has been, there will be a
release that includes the fixes to permit building with Xcode 12.

-a

On Wed, Apr 21, 2021 at 1:10 AM tdehnke@me.com wrote:

Issue #17777 has been updated by tdehnke (Tony Dehnke).

Newbie here, I jsut ran into this today on my Mac running MacOS 11.2.3 (Intel)

tdehnke@Tonys-MacBook-Pro-15 12vBiz % rbenv install 2.6.7
Downloading ruby-2.6.7.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.7.tar.bz2
Installing ruby-2.6.7...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 11.2.3 using ruby-build 20210420)

Inspect or clean up the working tree at /var/folders/r0/vw984xf56318dq54dzjk26wm0000gn/T/ruby-build.20210421115228.39383.OiFuid
Results logged to /var/folders/r0/vw984xf56318dq54dzjk26wm0000gn/T/ruby-build.20210421115228.39383.log

Last 10 log lines:
vm.c:2295:9: error: implicit declaration of function 'rb_native_mutex_destroy' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        rb_native_mutex_destroy(&vm->waitpid_lock);
        ^
vm.c:2489:34: warning: expression does not compute the number of elements in this array; element type is 'const int', not 'VALUE' (aka 'unsigned long') [-Wsizeof-array-div]
                             sizeof(ec->machine.regs) / sizeof(VALUE));
                                    ~~~~~~~~~~~~~~~~  ^
vm.c:2489:34: note: place parentheses around the 'sizeof(VALUE)' expression to silence this warning
1 warning and 1 error generated.
make: *** [vm.o] Error 1
make: *** Waiting for unfinished jobs....

Bug #17777: 2.6.7 fails to build on macOS: implicit declaration of function 'rb_native_mutex_destroy' is invalid in C99
https://bugs.ruby-lang.org/issues/17777#change-91638

  • Author: Eregon (Benoit Daloze)
  • Status: Closed
  • Priority: Normal
  • ruby -v: 2.6.7

* Backport: 2.6: REQUIRED, 2.7: DONTNEED, 3.0: DONTNEED

https://github.com/ruby/ruby-builder/runs/2271346109?check_suite_focus=true#step:14:11253

vm.c:2295:9: error: implicit declaration of function 'rb_native_mutex_destroy' is invalid in C99

There is also a warning below that might be worth solving:

vm.c:2489:34: warning: expression does not compute the number of elements in this array; element type is 'const int', not 'VALUE' (aka 'unsigned long') [-Wsizeof-array-div]
                             sizeof(ec->machine.regs) / sizeof(VALUE));
                                    ~~~~~~~~~~~~~~~~  ^
vm.c:2489:34: note: place parentheses around the 'sizeof(VALUE)' expression to silence this warning

--
https://bugs.ruby-lang.org/

Updated by usa (Usaku NAKAMURA) 4 months ago

  • Backport changed from 2.6: REQUIRED, 2.7: DONTNEED, 3.0: DONTNEED to 2.6: DONE, 2.7: DONTNEED, 3.0: DONTNEED

(hopefully) fixed at r67942.

Actions

Also available in: Atom PDF