Bug 1566178
| Summary: | ld: cannot find -lgcc when using libgccjit | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Marek Polacek <mpolacek> |
| Component: | gcc | Assignee: | Dave Malcolm <dmalcolm> |
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | unspecified | Docs Contact: | |
| Priority: | unspecified | ||
| Version: | 27 | CC: | aoliva, davejohansen, dmalcolm, fweimer, jakub, jwakely, law, mpolacek, msebor, nickc |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2018-08-10 14:38:52 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
I can reproduce with: libgccjit-7.3.1-2.fc26.x86_64 libgccjit-devel-7.3.1-2.fc26.x86_64 a.out fails the link, except when run from /tmp. On trying with: gcc_jit_context_set_bool_use_external_driver (ctxt, 1); it fails with: libgccjit.so: error trying to exec 'x86_64-redhat-linux-gcc-7.3.1': execvp: No such file or directory libgccjit.so: error: error invoking gcc driver: exit_status: 65280 err: 0 libgccjit.so: error: whilst attempting to run a driver named: x86_64-redhat-linux-gcc-7.3.1 libgccjit.so: error: PATH was: /usr/libexec/python2-sphinx:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/david/.local/bin:/home/david/bin gcc_jit_result_get_code: NULL result Segmentation fault (core dumped) On adding: sudo ln -s /usr/bin/gcc /usr/bin/x86_64-redhat-linux-gcc-7.3.1 then it works: $ ./a.out hello foo ...and with that symlink in place, it now works using the embedded driver, and that stops working if I remove that symlink. Am investigating. We have just /usr/bin/x86_64-redhat-linux-gcc-7 binary, not -7.3.1; and the reason for that is that Fedora gcc is configured with --with-gcc-major-version-only Perhaps something in jit doesn't honor this configure option then? Running with the embedded driver (the default), and manually hacking in "-v" to the driver invocation via:
(gdb) break gcc::jit::playback::context::invoke_embedded_driver
(gdb) watch global_options->x_verbose_flag
(gdb) set global_options->x_verbose_flag = 1
shows the following real differences between the outside vs inside /tmp cases (after manually hacking up the various irrelevant differences e.g. tmpdir names, process IDs, etc to be "XXXXXX").
diff -up outside-tmp.txt within-tmp.txt
--- outside-tmp.txt 2018-04-11 15:46:12.735802196 -0400
+++ within-tmp.txt 2018-04-11 15:46:21.544884909 -0400
@@ -11,10 +11,8 @@ COLLECT_GCC_OPTIONS='-m64' '-shared' '-o
as --64 -o /tmp/ccXXXXXX.o /tmp/libgccjit-XXXXXX/fake.s
Detaching after vfork from child process XXXXX.
COMPILER_PATH=
-LIBRARY_PATH=/lib/../lib64/:/usr/lib/../lib64/:/lib/:/usr/lib/
+LIBRARY_PATH=../lib/gcc/x86_64-redhat-linux/7/:../lib/gcc/:../lib/gcc/x86_64-redhat-linux/7/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:../lib/gcc/x86_64-redhat-linux/7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-m64' '-shared' '-o' '/tmp/libgccjit-XXXXXX/fake.so' '-fno-use-linker-plugin' '-mtune=generic' '-march=x86-64'
- ld --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared -o /tmp/libgccjit-XXXXXX/fake.so /lib/../lib64/crti.o crtbeginS.o -L/lib/../lib64 -L/usr/lib/../lib64 /tmp/ccXXXXXX.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed crtendS.o /lib/../lib64/crtn.o
+ ld --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared -o /tmp/libgccjit-XXXXXX/fake.so ../lib/gcc/x86_64-redhat-linux/7/../../../../lib64/crti.o ../lib/gcc/x86_64-redhat-linux/7/crtbeginS.o -L../lib/gcc/x86_64-redhat-linux/7 -L../lib/gcc -L../lib/gcc/x86_64-redhat-linux/7/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L../lib/gcc/x86_64-redhat-linux/7/../../.. /tmp/ccXXXXXX.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed ../lib/gcc/x86_64-redhat-linux/7/crtendS.o ../lib/gcc/x86_64-redhat-linux/7/../../../../lib64/crtn.o
Detaching after vfork from child process XXXXX.
-ld: cannot find crtbeginS.o: No such file or directory
-ld: cannot find -lgcc
-ld: cannot find -lgcc_s
+COLLECT_GCC_OPTIONS='-m64' '-shared' '-o' '/tmp/libgccjit-XXXXXX/fake.so' '-fno-use-linker-plugin' '-mtune=generic' '-march=x86-64'
In particular, LIBRARY_PATH goes from:
/lib/../lib64/
/usr/lib/../lib64/
/lib/
/usr/lib/
to:
../lib/gcc/x86_64-redhat-linux/7/
../lib/gcc/
../lib/gcc/x86_64-redhat-linux/7/../../../../lib64/
/lib/../lib64/
/usr/lib/../lib64/
../lib/gcc/x86_64-redhat-linux/7/../../../
/lib/
/usr/lib/
and the "ld" invocations' options go from:
ld --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu \
-m elf_x86_64 -shared -o /tmp/libgccjit-XXXXXX/fake.so \
/lib/../lib64/crti.o \
crtbeginS.o \
-L/lib/../lib64 \
-L/usr/lib/../lib64 \
/tmp/ccXXXXXX.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed \
crtendS.o \
/lib/../lib64/crtn.o
to:
ld --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu \
-m elf_x86_64 -shared -o /tmp/libgccjit-XXXXXX/fake.so \
../lib/gcc/x86_64-redhat-linux/7/../../../../lib64/crti.o \
../lib/gcc/x86_64-redhat-linux/7/crtbeginS.o \
-L../lib/gcc/x86_64-redhat-linux/7 \
-L../lib/gcc \
-L../lib/gcc/x86_64-redhat-linux/7/../../../../lib64 \
-L/lib/../lib64 \
-L/usr/lib/../lib64 \
-L../lib/gcc/x86_64-redhat-linux/7/../../.. \
/tmp/ccXXXXXX.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed \
../lib/gcc/x86_64-redhat-linux/7/crtendS.o \
../lib/gcc/x86_64-redhat-linux/7/../../../../lib64/crtn.o
(In reply to Jakub Jelinek from comment #2) > We have just > /usr/bin/x86_64-redhat-linux-gcc-7 > binary, not -7.3.1; and the reason for that is that Fedora gcc is configured > with > --with-gcc-major-version-only Aha - thanks. > Perhaps something in jit doesn't honor this configure option then? Indeed. gcc/configure.ac has: # Determine what GCC version number to use in filesystem paths. GCC_BASE_VER using config/acx.m4 to define get_gcc_base_ver honoring --with-gcc-major-version-only. Later on it has: # Generate gcc-driver-name.h containing GCC_DRIVER_NAME for the benefit # of jit/jit-playback.c. cat > gcc-driver-name.h <<EOF #define GCC_DRIVER_NAME "${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}" EOF So presumably the generation of GCC_DRIVER_NAME simply needs to use get_gcc_base_ver rather than gcc_BASEVER to properly respect --with-gcc-major-version-only. Am working on a fix for that. Notes to self: gcc/Makefile.in has: version := $(shell @get_gcc_base_ver@ $(BASEVER)) and: # Install the driver program as $(target_noncanonical)-gcc, # $(target_noncanonical)-gcc-$(version), and also as gcc if native. install-driver: installdirs xgcc$(exeext) (In reply to Jakub Jelinek from comment #2) > We have just > /usr/bin/x86_64-redhat-linux-gcc-7 > binary, not -7.3.1; and the reason for that is that Fedora gcc is configured > with > --with-gcc-major-version-only > Perhaps something in jit doesn't honor this configure option then? I've filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85384 to cover that. Should be fixed now. |
E.g. this: #include <libgccjit.h> int main (int argc, char **argv) { gcc_jit_context *ctxt; gcc_jit_result *result; typedef int (*some_fn_type) (const char *); ctxt = gcc_jit_context_acquire (); gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); gcc_jit_type *const_char_ptr_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); gcc_jit_param *param_name = gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); gcc_jit_function *func = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "some_fn", 1, ¶m_name, 0); gcc_jit_param *param_format = gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); gcc_jit_function *printf_func = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_IMPORTED, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT), "printf", 1, ¶m_format, 1); gcc_jit_rvalue *args[2]; args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); args[1] = gcc_jit_param_as_rvalue (param_name); gcc_jit_block *block = gcc_jit_function_new_block (func, "initial"); gcc_jit_block_add_eval ( block, NULL, gcc_jit_context_new_call (ctxt, NULL, printf_func, 2, args)); gcc_jit_block_end_with_void_return (block, NULL); result = gcc_jit_context_compile (ctxt); gcc_jit_context_release (ctxt); some_fn_type some_fn = (some_fn_type)gcc_jit_result_get_code (result, "some_fn"); some_fn ("foo"); gcc_jit_result_release (result); } when compiled as $ gcc -g -Wall -Werror jit.c -lgccjit and run in e.g. /tmp/foo gives errors: $ ./a.out ld: cannot find -lgcc ld: cannot find -lgcc_s libgccjit.so: error: error invoking gcc driver gcc_jit_result_get_code: NULL result Segmentation fault (core dumped) The problem is that libgccjit seems to use relative paths, as can be seen in $ strace ./a.out so the proper libraries aren't found. If the binary is run e.g. from /tmp, it works as expected.