[ruby-core:104922] [Ruby master Bug#18000] have_library doesn't work when ruby is compiled with --disable-shared --disable-install-static-library
From:
XrXr@...
Date:
2021-08-14 19:36:15 UTC
List:
ruby-core #104922
Issue #18000 has been updated by alanwu (Alan Wu).
No objection from me to drop support for the `--disable-shared
--disable-install-static-library` config. I agree with Jean that it's an
improvement to give a clear message and fail fast.
> With that combination, shouldn't we drop the header files too?
If we are keen on supporting that config, it should be possible to add
special handling to `have_func` and other `mkmf` methods to work without
libruby. On glibc platforms at least, this could be done by building the test
program as a shared library, and then using dlopen(3) with `RTLD_NOW` to check
if every symbol resolves. The test program would still need the headers.
This testing process is similar to how Ruby would require the extension
once it's built, so maybe in some ways it's also a more accurate test.
It's already possible today to build an extension without libruby using
only the headers. Here's a small demo for it:
```ruby
# A small demo for building an extension against a Ruby built with
# --disable-shared without libruby.
require 'rbconfig'
config = RbConfig::CONFIG
hdr_dir = config['rubyhdrdir']
arch_hdr_dir = config['rubyarchhdrdir']
# Note how this doesn't link against libruby at all
compile_command = "cc -shared -fpic -o ext.so -I #{hdr_dir} -I #{arch_hdr_dir} ext.c"
File.write("ext.c", <<~EOM)
#include <ruby/ruby.h>
void
Init_ext(void)
{
// Using two Ruby symbols. The static Ruby executable export these.
rb_raise(rb_eRuntimeError, "hello from ext");
}
EOM
puts " Enabled shared: #{config['ENABLE_SHARED']}"
puts "Compile command: #{compile_command}"
system(compile_command)
require_relative 'ext'
```
Adding support takes more effort than rejecting the config outright of
course. Another easy option is making `mkmf` error on that config.
We could still leave the headers for people that want to build
extensions without `mkmf`. Maybe there are users writing extensions
in languages not supported by `mkmf`.
----------------------------------------
Bug #18000: have_library doesn't work when ruby is compiled with --disable-shared --disable-install-static-library
https://bugs.ruby-lang.org/issues/18000#change-93289
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
Related [Feature #12845]
If you compile ruby with `--disable-shared --disable-install-static-library`, then many C-extension won't compile anymore. For instance `RedCloth`
```ruby
# extconf.rb
require 'mkmf'
CONFIG['warnflags'].gsub!(/-Wshorten-64-to-32/, '') if CONFIG['warnflags']
$CFLAGS << ' -O0 -Wall ' if CONFIG['CC'] =~ /gcc/
dir_config("redcloth_scan")
have_library("c", "main")
create_makefile("redcloth_scan")
```
```
#mkmf.log
"gcc -o conftest -I/usr/local/include/ruby-3.1.0/x86_64-linux -I/usr/local/include/ruby-3.1.0/ruby/backward -I/usr/local/include/ruby-3.1.0 -I. -I/usr/local/include -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wundef -O0 -Wall conftest.c -L. -L/usr/local/lib -Wl,-rpath,/usr/local/lib -L. -L/usr/local/lib -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lruby-static -lz -lpthread -lrt -lrt -lgmp -ldl -lcrypt -lm
-lm -lc"
/usr/bin/ld: cannot find -lruby-static
collect2: error: ld returned 1 exit status
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: int main(int argc, char **argv)
4: {
5: return !!argv[argc];
6: }
/* end */
```
We'd like to use both flags, the first because it provide a small performance improvement, the second because `libruby-static.a` is enormous (up to 120MiB on debug builds).
@alanwu says it's theoretically possible to compile with just the headers.
---Files--------------------------------
no-static-no-shared.diff (2.55 KB)
rb_prefix_hack.diff (1.76 KB)
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>