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.
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.