cbor-ruby icon indicating copy to clipboard operation
cbor-ruby copied to clipboard

Gem not compatible with gcc 15

Open SamSaffron opened this issue 7 months ago • 1 comments

gem install cbor
Building native extensions. This could take a while...
ERROR:  Error installing cbor:
	ERROR: Failed to build gem native extension.

    current directory: /home/sam/.gem/ruby/3.4.4/gems/cbor-0.5.9.8/ext/cbor
/home/sam/.rubies/ruby-3.4.4/bin/ruby extconf.rb
checking for ruby/st.h... yes
checking for st.h... no
checking for rb_str_replace() in ruby.h... yes
checking for rb_big_new() in ruby.h... yes
checking for rb_intern_str() in ruby.h... yes
checking for rb_sym2str() in ruby.h... yes
checking for rb_str_intern() in ruby.h... yes
checking for rb_integer_unpack() in ruby.h... yes
creating Makefile

current directory: /home/sam/.gem/ruby/3.4.4/gems/cbor-0.5.9.8/ext/cbor
make DESTDIR\= sitearchdir\=./.gem.20250521-1015015-blwi54 sitelibdir\=./.gem.20250521-1015015-blwi54 clean

current directory: /home/sam/.gem/ruby/3.4.4/gems/cbor-0.5.9.8/ext/cbor
make DESTDIR\= sitearchdir\=./.gem.20250521-1015015-blwi54 sitelibdir\=./.gem.20250521-1015015-blwi54
compiling buffer.c
In file included from /home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/arithmetic/long.h:42,
                 from /home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/arithmetic/int.h:26,
                 from /home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/arithmetic/char.h:23,
                 from /home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/arithmetic.h:24,
                 from /home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/ruby.h:28,
                 from /home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby.h:38,
                 from compat.h:30,
                 from buffer.h:32,
                 from buffer.c:28:
/home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/special_consts.h:137:15: error: unknown type name ‘bool’
  137 | static inline bool/home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/special_consts.h:31:1: note: ‘bool’ is defined in header ‘<stdbool.h>’; this is probably fixable by adding ‘#include <stdbool.h>’

gcc 15 which is slowly rolling out, can not compile cbor. Quite a few gems are in this state now.

SamSaffron avatar May 21 '25 05:05 SamSaffron

/home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/special_consts.h:137:15: error: unknown type name ‘bool’ 137 | static inline bool/home/sam/.rubies/ruby-3.4.4/include/ruby-3.4.0/ruby/internal/special_consts.h:31:1: note: ‘bool’ is defined in header ‘<stdbool.h>’; this is probably fixable by adding ‘#include <stdbool.h>’


gcc 15 which is slowly rolling out, can not compile cbor. Quite a few gems are in this state now.

Right. Not the first issue of this kind.

The hard part usually is not fixing for the newest compiler, but making sure that the gem remains compilable on older compilers. To really test this, one would have to prepare a rather elaborate CI environment.

So the next step for me is looking for how this problem was solved for other gems.

cabo avatar May 21 '25 11:05 cabo

Is there any alternatives/workarounds for this issue?

TiuTalk avatar Jun 08 '25 23:06 TiuTalk

Is there any alternatives/workarounds for this issue?

I didn't manage to set up the environments to test this with gcc15 before going on vacation (sorry about that), but I'm back now, and this has high priority. The error appears to occur inside Ruby's include files, and at this point I do not know why (and I do not yet have an environment to reproduce the error). So if you want to help me, please describe your environment in more detail so I might be able to replicate it. Also, this is unlikely to be an issue specific just to the cbor gem, so it would be good to investigate how other gems handle it.

cabo avatar Jun 09 '25 09:06 cabo

So if you want to help me, please describe your environment in more detail so I might be able to replicate it.

I'm not well versed in C and compiling, so the terminology might be wrong here.. but I'm confident this is related to which gcc ( and gcclibc?) version is being used to compile the native extension.

I noticed similar issues while compiling google-protobuf gem too.

I'm away from my computer, so I will share the system specs and logs later today, but if I remember correctly this issue was seen while compiling cbor 0.5.9.8 on Ruby 3.4.1 (installed via asdf), in an EndeavourOS (Arch Linux) environment, with the latest version of gcc (15 something).

TiuTalk avatar Jun 09 '25 11:06 TiuTalk

Funny enough, I had a similar issue in the past https://github.com/cabo/cbor-ruby/issues/22

TiuTalk avatar Jun 09 '25 11:06 TiuTalk

@cabo here are the relevant versions and the install log, please let me know if I can provide any more information:

https://gist.github.com/TiuTalk/adb7e49aa815ea8a76fef7e811486e3f

➜ uname -a
Linux lambda 6.14.10-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 04 Jun 2025 18:52:35 +0000 x86_64 GNU/Linux

➜ ruby -v
ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux]

➜ bundle -v
Bundler version 2.6.2

➜ gem -v
3.6.2

➜ asdf --version
asdf version 0.17.0-arch (revision d536803)

➜ gcc --version
gcc (GCC) 15.1.1 20250425

➜ yay -Ss libcbor
extra/libcbor 0.11.0-1 (42.7 KiB 165.1 KiB) (Installed)
    C library for parsing and generating CBOR, the general-purpose schema-less binary data format

TiuTalk avatar Jun 09 '25 13:06 TiuTalk

I was able to install it (and other gems that were giving me trouble) by downgrading to gcc:

➜ gcc --version
gcc (GCC) 14.2.1 20250207

TiuTalk avatar Jun 09 '25 13:06 TiuTalk

There are actually two problems here:

  1. Instead of setting CFLAGS directly, append_cflags should be used. Related change in the io-event gem: https://github.com/socketry/io-event/pull/137. I see that https://github.com/cabo/cbor-ruby/pull/28 drops the std=c99 entirely, but perhaps converting to append_cflags would be safer here: https://github.com/cabo/cbor-ruby/blob/4e8b2ec982f41cfcd6568a429add205c8259f470/ext/cbor/extconf.rb#L12
  2. For GCC 15, the Ruby interpreter should include <stdbool.h> by default. Currently it only does it if HAVE_STDBOOL_H is defined, which is only the case for win32 builds: https://github.com/ruby/ruby/blob/f91ea2332420bcabfafbb2540238f4f8422bfb97/include/ruby/internal/stdbool.h#L38

As mentioned in https://gcc.gnu.org/gcc-15/porting_to.html#c23:

In C99 and later you can use #include <stdbool.h> which provides definitions of bool, true, and false compatible with C23.

You can see that with this simple test program:

#include <stdio.h>

int main() {
  bool test = false;

  return test ? 1 : 0;
}

If I compile this with -std=c99 or even std=gnu17, I get these errors:

# gcc -std=c99 /tmp/test.c
/tmp/test.c: In function 'main':
/tmp/test.c:4:3: error: unknown type name 'bool'
    4 |   bool test = false;
      |   ^~~~
/tmp/test.c:2:1: note: 'bool' is defined in header '<stdbool.h>'; this is probably fixable by adding '#include <stdbool.h>'
    1 | #include <stdio.h>
  +++ |+#include <stdbool.h>
    2 | 

However, if I omit std=, it compiles fine without the #include <stdbool.h>:

# gcc /tmp/test.c
# 

stanhu avatar Jul 23 '25 18:07 stanhu

Actually it seems that autoconf should have defined HAVE_STDBOOL_H: https://github.com/autotools-mirror/autoconf/blob/1f38316f6af7bf63e5e7dd187ff6456e07ad743e/lib/autoconf/headers.m4#L651-L659

Yet if I install ruby 3.4.4 via mise on fedora:42, I see this in the build logs:

configure:13530: checking for stdbool.h that conforms to C99
configure:13646: gcc -c -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2  -O3 -fno-fast-math -ggdb3    conftest.c >&5
conftest.c:103:17: error: #error "bool is not defined"
  103 |                #error "bool is not defined"
      |                 ^~~~~
conftest.c:106:17: error: #error "false is not defined"
  106 |                #error "false is not defined"
      |                 ^~~~~
conftest.c:109:17: error: #error "true is not defined"
  109 |                #error "true is not defined"
      |                 ^~~~~
configure:13646: $? = 1

Attached is the test program used by configure:

test-bool.txt

It seems that this test is outdated: https://cgit.git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6dcecb780a69bd208088d666b299e92aa7ae7e80. If I do this:

autoreconf -fiv
./configure

Then it works:

checking for stdbool.h that conforms to C99 or later... yes

It seems that Fedora's 42 ruby-devel package appears to have have this correctly set:

/usr/include/ruby/config-x86_64.h:#define HAVE_STDBOOL_H 1

stanhu avatar Jul 23 '25 19:07 stanhu

I see that https://bugs.ruby-lang.org/issues/21340 already fixed the stdbool issue a month ago.

stanhu avatar Jul 23 '25 20:07 stanhu

I see that https://bugs.ruby-lang.org/issues/21340 already fixed the stdbool issue a month ago.

I believe the latest Rubies contain that fix (and maybe others) for GCC 15 compilation.

  • https://github.com/ruby/ruby/releases/tag/v3_4_5 (post)
  • https://github.com/ruby/ruby/releases/tag/v3_3_9 (post)
  • https://github.com/ruby/ruby/releases/tag/v3_2_9 (post)

larouxn avatar Jul 24 '25 11:07 larouxn

Thanks, that is helpful.

I think https://github.com/cabo/cbor-ruby/pull/29 is still useful because not only because it will ensue older Ruby versions won't have an issue, but it also ensures other C compilers will build properly with this gem.

stanhu avatar Jul 25 '25 05:07 stanhu