From 0ff52311c3623479b3e43f2baa618be9461ec5c5 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 23 Dec 2024 19:43:50 +0100 Subject: [PATCH] - Fix problem where crt1 was linked for dynamic libraries on Linux and BSD. #1710 --- .github/workflows/main.yml | 8 ++++---- releasenotes.md | 1 + src/compiler/linker.c | 33 ++++++++++++++++----------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 83862d56c..403034ba8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,8 +66,8 @@ jobs: - name: Compile and run dynlib-test run: | cd resources/examples/dynlib-test - ..\..\..\build\${{ matrix.build_type }}\c3c.exe dynamic-lib add.c3 - ..\..\..\build\${{ matrix.build_type }}\c3c.exe compile-run test.c3 -l ./add.lib + ..\..\..\build\${{ matrix.build_type }}\c3c.exe -vv dynamic-lib add.c3 + ..\..\..\build\${{ matrix.build_type }}\c3c.exe -vv compile-run test.c3 -l ./add.lib - name: Vendor-fetch run: | @@ -320,7 +320,7 @@ jobs: - name: Compile and run dynlib-test run: | cd resources/examples/dynlib-test - ../../../build/c3c dynamic-lib add.c3 + ../../../build/c3c -vv dynamic-lib add.c3 mv add.so libadd.so cc test.c -L. -ladd -Wl,-rpath=. ./a.out @@ -639,7 +639,7 @@ jobs: - name: Compile and run dynlib-test run: | cd resources/examples/dynlib-test - ../../../build/c3c dynamic-lib add.c3 + ../../../build/c3c -vv dynamic-lib add.c3 ../../../build/c3c compile-run test.c3 -l ./add.dylib - name: Compile run unit tests diff --git a/releasenotes.md b/releasenotes.md index 9c6fc36c8..3e21d112a 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -15,6 +15,7 @@ - Fix bug when a macro calling an extern function was called in another module also declaring and calling the same function. #1690 - `static-lib` and `dynamic-lib` options from the command line now produces headers. - Fix bug outputting exported functions without predefined extname. +- Fix problem where crt1 was linked for dynamic libraries on Linux and BSD. #1710 ### Stdlib changes - Increase BitWriter.write_bits limit up to 32 bits. diff --git a/src/compiler/linker.c b/src/compiler/linker.c index 0953e8de6..fb0a0fc5a 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -12,11 +12,11 @@ const char *quote_arg = "\""; const char *concat_arg = ":"; const char *concat_quote_arg = "+"; const char *concat_file_arg = "/"; -#define add_quote_arg(arg_) vec_add(*args_ref, quote_arg); vec_add(*args_ref, (arg_)) +#define add_quote_arg(arg_) do { vec_add(*args_ref, quote_arg); vec_add(*args_ref, (arg_)); } while(0) #define add_plain_arg(arg_) vec_add(*args_ref, (arg_)) -#define add_concat_file_arg(arg_, arg2_) vec_add(*args_ref, concat_file_arg); vec_add(*args_ref, (arg_)); vec_add(*args_ref, (arg2_)) -#define add_concat_arg(arg_, arg2_) vec_add(*args_ref, concat_arg); vec_add(*args_ref, (arg_)); vec_add(*args_ref, (arg2_)) -#define add_concat_quote_arg(arg_, arg2_) vec_add(*args_ref, concat_quote_arg); vec_add(*args_ref, (arg_)); vec_add(*args_ref, (arg2_)) +#define add_concat_file_arg(arg_, arg2_) do { vec_add(*args_ref, concat_file_arg); vec_add(*args_ref, (arg_)); vec_add(*args_ref, (arg2_)); } while(0) +#define add_concat_arg(arg_, arg2_) do { vec_add(*args_ref, concat_arg); vec_add(*args_ref, (arg_)); vec_add(*args_ref, (arg2_)); } while(0) +#define add_concat_quote_arg(arg_, arg2_) do { vec_add(*args_ref, concat_quote_arg); vec_add(*args_ref, (arg_)); vec_add(*args_ref, (arg2_)); } while(0) static char *assemble_linker_command(const char **args, bool extra_quote); static unsigned assemble_link_arguments(const char **arguments, unsigned len); @@ -331,7 +331,7 @@ static const char *find_linux_crt_begin(void) return path; } -static void linker_setup_linux(const char ***args_ref, Linker linker_type) +static void linker_setup_linux(const char ***args_ref, Linker linker_type, bool is_dylib) { linking_add_link(&compiler.linking, "dl"); if (linker_type == LINKER_CC) @@ -374,16 +374,16 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type) } if (is_pie_pic(compiler.platform.reloc_model)) { - add_concat_file_arg(crt_dir, "Scrt1.o"); - add_concat_file_arg(crt_begin_dir, "crtbeginS.o"); add_concat_file_arg(crt_dir, "crti.o"); + if (!is_dylib) add_concat_file_arg(crt_dir, "Scrt1.o"); + add_concat_file_arg(crt_begin_dir, "crtbeginS.o"); add_concat_file_arg(crt_begin_dir, "crtendS.o"); } else { - add_concat_file_arg(crt_dir, "crt1.o"); - add_concat_file_arg(crt_begin_dir, "crtbegin.o"); add_concat_file_arg(crt_dir, "crti.o"); + if (!is_dylib) add_concat_file_arg(crt_dir, "crt1.o"); + add_concat_file_arg(crt_begin_dir, "crtbegin.o"); add_concat_file_arg(crt_begin_dir, "crtend.o"); } add_concat_file_arg(crt_dir, "crtn.o"); @@ -399,7 +399,7 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type) add_plain_arg(ld_target(compiler.platform.arch)); } -static void linker_setup_freebsd(const char ***args_ref, Linker linker_type) +static void linker_setup_freebsd(const char ***args_ref, Linker linker_type, bool is_dylib) { if (linker_type == LINKER_CC) { linking_add_link(&compiler.linking, "m"); @@ -421,20 +421,19 @@ static void linker_setup_freebsd(const char ***args_ref, Linker linker_type) { add_plain_arg("--gc-sections"); } - if (is_pie_pic(compiler.platform.reloc_model)) { add_plain_arg("-pie"); - add_concat_file_arg(crt_dir, "Scrt1.o"); - add_concat_file_arg(crt_dir, "crtbeginS.o"); add_concat_file_arg(crt_dir, "crti.o"); + if (!is_dylib) add_concat_file_arg(crt_dir, "Scrt1.o"); + add_concat_file_arg(crt_dir, "crtbeginS.o"); add_concat_file_arg(crt_dir, "crtendS.o"); } else { - add_concat_file_arg(crt_dir, "crt1.o"); - add_concat_file_arg(crt_dir, "crtbegin.o"); add_concat_file_arg(crt_dir, "crti.o"); + if (!is_dylib) add_concat_file_arg(crt_dir, "crt1.o"); + add_concat_file_arg(crt_dir, "crtbegin.o"); add_concat_file_arg(crt_dir, "crtend.o"); } add_concat_file_arg(crt_dir, "crtn.o"); @@ -546,10 +545,10 @@ static bool linker_setup(const char ***args_ref, const char **files_to_link, uns case OS_TYPE_FREE_BSD: case OS_TYPE_OPENBSD: case OS_TYPE_NETBSD: - linker_setup_freebsd(args_ref, linker_type); + linker_setup_freebsd(args_ref, linker_type, is_dylib); break; case OS_TYPE_LINUX: - linker_setup_linux(args_ref, linker_type); + linker_setup_linux(args_ref, linker_type, is_dylib); break; case OS_TYPE_UNKNOWN: if (link_libc())