| 970 | } |
| 971 | |
| 972 | bool create_shared_library ( const char * objFilePath, const char * libraryName, [[maybe_unused]] const char * dasLib, const char * customLinker, const char * extraLinkerArgs, bool isShared, bool linkWholeLib, Context *context ) { |
| 973 | // cmd is built via fmt::format (heap-allocated std::string) rather |
| 974 | // than a fixed stack buffer — long paths (deep build roots, spaces, |
| 975 | // long extraLinkerArgs) can easily exceed a few hundred bytes, and |
| 976 | // a fixed buffer would silently corrupt the stack on overflow. |
| 977 | const char * extra = (extraLinkerArgs && extraLinkerArgs[0]) ? extraLinkerArgs : ""; |
| 978 | const auto paths = get_real_lib_linker_paths(dasLib, customLinker, isShared, linkWholeLib); |
| 979 | const auto & linker = paths.linker; |
| 980 | const auto & runtimeLibrary = paths.runtimeLibrary; |
| 981 | const auto & compilerLibrary = paths.compilerLibrary; |
| 982 | |
| 983 | #if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) |
| 984 | if (!check_file_present(runtimeLibrary.c_str())) { |
| 985 | LOG(LogLevel::error) << "File '" << runtimeLibrary << "' , containing daslang runtime library, does not exist\n"; |
| 986 | return false; |
| 987 | } |
| 988 | #endif |
| 989 | if (!check_file_present(objFilePath)) { |
| 990 | LOG(LogLevel::error) << "File '" << objFilePath << "' , containing compiled definitions, does not exist\n"; |
| 991 | return false; |
| 992 | } |
| 993 | |
| 994 | std::string cmd; |
| 995 | #if defined(_WIN32) || defined(_WIN64) |
| 996 | #if defined(_MSC_VER) |
| 997 | // MSVC clang-cl: -DLL marks shared, -link separates link-only |
| 998 | // flags, -OUT: names the output, msvcrt.lib pulls the import |
| 999 | // CRT. Outer doubled quotes wrap the whole command for cmd.exe |
| 1000 | // because the linker path itself contains spaces on Program |
| 1001 | // Files installs. |
| 1002 | const auto linkerParam = isShared ? "-DLL" : ""; |
| 1003 | cmd = compilerLibrary.empty() |
| 1004 | ? fmt::format(FMT_STRING("\"\"{}\" \"{}\" \"{}\" msvcrt.lib {} -link {} -OUT:\"{}\" 2>&1\""), linker.c_str(), objFilePath, runtimeLibrary.c_str(), extra, linkerParam, libraryName) |
| 1005 | : fmt::format(FMT_STRING("\"\"{}\" \"{}\" \"{}\" \"{}\" msvcrt.lib {} -link {} -OUT:\"{}\" 2>&1\""), linker.c_str(), objFilePath, runtimeLibrary.c_str(), compilerLibrary.c_str(), extra, linkerParam, libraryName); |
| 1006 | #else |
| 1007 | // mingw clang/gcc: Unix-flavored driver, -shared/-o syntax. |
| 1008 | // No rpath on Windows (DLLs resolve via PATH / LoadLibrary |
| 1009 | // search order), so the linux branch's rpath escape is |
| 1010 | // dropped. The linux branch's -Wl,--no-as-needed is also |
| 1011 | // dropped: on ELF, --no-as-needed forces a DT_NEEDED entry |
| 1012 | // for libraries that the linker would otherwise mark as |
| 1013 | // not-required (lazy bind). PE/COFF has no such concept — |
| 1014 | // listed libraries are always recorded in the import table, |
| 1015 | // so the flag has no effect. Worse, lld on newer mingw |
| 1016 | // sysroots rejects --no-as-needed as an unknown argument |
| 1017 | // (older clangs / GNU ld silently ignore it, which is why |
| 1018 | // this only surfaces on fresh CI installs). |
| 1019 | // Outer doubled quotes `\"...2>&1\"` wrap the whole command |
| 1020 | // — popen → cmd.exe strips one quote pair, leaving the |
| 1021 | // inner per-arg quotes intact. Without this wrap cmd.exe |
| 1022 | // misparses the very first quoted token as the command name. |
| 1023 | const auto linkerParam = isShared ? "-shared" : ""; |
| 1024 | cmd = compilerLibrary.empty() |
| 1025 | ? fmt::format(FMT_STRING("\"\"{}\" {} -o \"{}\" \"{}\" \"{}\" {} 2>&1\""), |
| 1026 | linker.c_str(), linkerParam, libraryName, objFilePath, runtimeLibrary.c_str(), extra) |
| 1027 | : fmt::format(FMT_STRING("\"\"{}\" {} -o \"{}\" \"{}\" \"{}\" \"{}\" {} 2>&1\""), |
| 1028 | linker.c_str(), linkerParam, libraryName, objFilePath, runtimeLibrary.c_str(), compilerLibrary.c_str(), extra); |
| 1029 | #endif |
nothing calls this directly
no test coverage detected