diff --git a/.gnfiles/build/toolchain/common/BUILD.gn b/.gnfiles/build/toolchain/common/BUILD.gn index d0d7990..067641b 100644 --- a/.gnfiles/build/toolchain/common/BUILD.gn +++ b/.gnfiles/build/toolchain/common/BUILD.gn @@ -119,6 +119,11 @@ config("allow_undefined") { "dynamic_lookup", ] } + # Although MinGW linker (ld) does actually silently accept the + # --allow-shlib-undefined option, but it can't do anything on PE targets. + # On Windows platform we have to allow undefined symbols in another way. + # (e.g. change ten_runtime_go to static library) + # Ref: https://github.com/llvm/llvm-project/issues/55245 } config("disallow_undefined") { diff --git a/.gnfiles/build/toolchain/mingw/BUILD.gn b/.gnfiles/build/toolchain/mingw/BUILD.gn index 2978bf4..cc276d5 100644 --- a/.gnfiles/build/toolchain/mingw/BUILD.gn +++ b/.gnfiles/build/toolchain/mingw/BUILD.gn @@ -45,16 +45,16 @@ config("debug") { defines = [ "_DEBUG" ] cflags = [ "-g" ] cflags_cc = [] - ldflags = [ - # Note: Do NOT use -static here, as it prevents linking with .dll.a import libraries - # (ten_runtime and ten_utils) - # Instead, use -Wl,-Bstatic/-Bdynamic to selectively static link libraries - "-Wl,-Bstatic", - "-lgcc", # Static link libgcc (avoids libgcc_s_seh-1.dll) - "-lstdc++", # Static link libstdc++ (avoids libstdc++-6.dll) - "-lpthread", # Static link pthread (avoids libwinpthread-1.dll) - "-Wl,-Bdynamic", # Switch back to dynamic linking for other libraries - ] + + # Note: Static linking of libgcc/libstdc++/pthread is handled in mingw.gni + # at the END of the link command (in rspfile_content) but not here. Because + # GNU ld is a single-pass linker and libraries must appear AFTER object files + # that reference them. + # Ref: https://sourceware.org/binutils/docs/ld/Options.html + # "...an undefined symbol in an object appearing later on the command line + # will not cause the linker to search the archive again." + ldflags = [] + libs = default_libs } @@ -65,17 +65,15 @@ config("release") { "-g", # Keep debug info for backtraces even in release ] cflags_cc = [] - ldflags = [ - "-Wl,-O2", - # Note: Do NOT use -static here, as it prevents linking with .dll.a import libraries - # (ten_runtime and ten_utils) - # Instead, use -Wl,-Bstatic/-Bdynamic to selectively static link libraries - "-Wl,-Bstatic", - "-lgcc", # Static link libgcc (avoids libgcc_s_seh-1.dll) - "-lstdc++", # Static link libstdc++ (avoids libstdc++-6.dll) - "-lpthread", # Static link pthread (avoids libwinpthread-1.dll) - "-Wl,-Bdynamic", # Switch back to dynamic linking for other libraries - ] + + # Note: Static linking of libgcc/libstdc++/pthread is handled in mingw.gni + # at the END of the link command (in rspfile_content) but not here. Because + # GNU ld is a single-pass linker and libraries must appear AFTER object files + # that reference them. + # Ref: https://sourceware.org/binutils/docs/ld/Options.html + # "...an undefined symbol in an object appearing later on the command line + # will not cause the linker to search the archive again." + ldflags = [ "-Wl,-O2" ] libs = default_libs } diff --git a/.gnfiles/build/toolchain/mingw/mingw.gni b/.gnfiles/build/toolchain/mingw/mingw.gni index 298566d..59484db 100644 --- a/.gnfiles/build/toolchain/mingw/mingw.gni +++ b/.gnfiles/build/toolchain/mingw/mingw.gni @@ -131,8 +131,17 @@ template("mingw_toolchain") { rspfile = sofile + ".rsp" pool = "//.gnfiles/build/toolchain:link_pool" + # Note: Static linking flags (-Wl,-Bstatic -lgcc -lstdc++ -lpthread -Wl,-Bdynamic) + # are placed at the END of rspfile_content, after all other libs. Or else dynamic + # libs (e.g. simple_http_server_cpp.dll) that depends on libgcc_s_seh-1.dll and + # libstdc++-6.dll will not be correctly loaded. + # This is critical because GNU ld is a single-pass linker - libraries must + # appear AFTER the object files that reference them. + # Ref: https://sourceware.org/binutils/docs/ld/Options.html + # "...an undefined symbol in an object appearing later on the command line + # will not cause the linker to search the archive again." command = "cmd /c del /f /q \"$sofile\" \"$implibfile\" 2>nul & $ld -shared {{ldflags}} -Wl,--allow-multiple-definition -o \"$sofile\" -Wl,--out-implib=\"$implibfile\" -Wl,--start-group @\"$rspfile\" -Wl,--end-group" - rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" + rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix -Wl,-Bstatic -lgcc -lstdc++ -lpthread -Wl,-Bdynamic" description = "LD $sofile $implibfile" default_output_extension = ".dll" @@ -158,8 +167,9 @@ template("mingw_toolchain") { rspfile = sofile + ".rsp" pool = "//.gnfiles/build/toolchain:link_pool" + # Note: Static linking flags are placed at the END of rspfile_content. command = "cmd /c del /f /q \"{{output}}\" 2>nul & $ld -shared {{ldflags}} -Wl,--allow-multiple-definition -o \"{{output}}\" -Wl,--start-group @\"$rspfile\" -Wl,--end-group" - rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix" + rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix -Wl,-Bstatic -lgcc -lstdc++ -lpthread -Wl,-Bdynamic" description = "LD {{output}}" default_output_extension = ".dll" @@ -179,8 +189,9 @@ template("mingw_toolchain") { default_output_extension = ".exe" default_output_dir = "{{root_out_dir}}" + # Note: Static linking flags are placed at the END of rspfile_content. command = "cmd /c del /f /q \"{{output}}\" 2>nul & $ld {{ldflags}} -Wl,--allow-multiple-definition -o \"{{output}}\" -Wl,--start-group @\"$rspfile\" -Wl,--end-group" - rspfile_content = "-Wl,--no-whole-archive $inputs_section_prefix {{inputs}} {{solibs}} $libs_section_prefix {{libs}} $libs_section_postfix" + rspfile_content = "-Wl,--no-whole-archive $inputs_section_prefix {{inputs}} {{solibs}} $libs_section_prefix {{libs}} $libs_section_postfix -Wl,-Bstatic -lgcc -lstdc++ -lpthread -Wl,-Bdynamic" description = "LD {{output}}" outputs = [ outfile ]