From fa06d5a76b02018980ccc12fcd52ea96bd894c81 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 9 May 2022 13:19:47 +0200 Subject: Use lld or gold if installed --- CMakeLists.txt | 1 + include/Linker.hpp | 4 ++++ src/GlobalLib.cpp | 5 +++++ src/Linker.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 12 ++++++++++-- 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/Linker.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 719e984..958db38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set(SOURCE_FILES src/Platform.cpp src/Version.cpp src/VersionParser.cpp + src/Linker.cpp depends/libninja/src/Ninja.cpp) diff --git a/include/Linker.hpp b/include/Linker.hpp index acf31e4..b2e64fe 100644 --- a/include/Linker.hpp +++ b/include/Linker.hpp @@ -2,12 +2,16 @@ #define SIBS_LINKER_HPP #include +#include namespace sibs { using LinkerFlagCallbackFunc = std::function; using GlobalIncludeDirCallbackFunc = std::function; using CflagsCallbackFunc = std::function; + + bool is_gold_linker_installed(); + bool is_lld_linker_installed(); } #endif //SIBS_LINKER_HPP diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp index b390571..dc45e23 100644 --- a/src/GlobalLib.cpp +++ b/src/GlobalLib.cpp @@ -156,6 +156,11 @@ namespace sibs sibsConfig.platform = parentConfig.platform; sibsConfig.packaging = parentConfig.packaging; sibsConfig.bundling = parentConfig.bundling; + sibsConfig.setSanitize(parentConfig.getSanitize()); + sibsConfig.linker = parentConfig.linker; + sibsConfig.use_lto = parentConfig.use_lto; + sibsConfig.skipCompile = parentConfig.skipCompile; + sibsConfig.include_debug_symbols_in_release = parentConfig.include_debug_symbols_in_release; Result result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); if (result.isErr()) return result; diff --git a/src/Linker.cpp b/src/Linker.cpp new file mode 100644 index 0000000..7d90d46 --- /dev/null +++ b/src/Linker.cpp @@ -0,0 +1,49 @@ +#include "../include/Linker.hpp" +#include "../include/FileUtil.hpp" + +static void split_string(const std::string &str, char delimiter, std::function callback) { + size_t index = 0; + while(index < str.size()) { + const size_t end_index = str.find(delimiter, index); + if(end_index == std::string::npos) + break; + + if(!callback(&str[index], end_index - index)) + break; + + index = end_index + 1; + } +} + +namespace sibs +{ + static bool is_linker_installed(const char *linker_binary_name) { + const char *path = getenv("PATH"); + if(!path) + return false; + + bool linker_found = false; + split_string(path, ':', [&](const char *str, size_t size) { + std::string fullpath(str, size); + fullpath += "/"; + fullpath += linker_binary_name; + + if(getFileType(fullpath.c_str()) == FileType::REGULAR) { + linker_found = true; + return false; + } + + return true; + }); + + return linker_found; + } + + bool is_gold_linker_installed() { + return is_linker_installed("ld.gold"); + } + + bool is_lld_linker_installed() { + return is_linker_installed("ld.lld"); + } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2592135..3c2ad46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -138,7 +138,7 @@ static void usageBuild(bool run) printf(" --platform The platform to build for - Optional (default: the running platform)\n"); printf(" --lto Use link-time optimization. May increase compile times - Optional (default: not used)\n"); printf(" --debug-symbols Include debug symbols in release mode - Optional (default: not used)\n"); - printf(" --linker=linker The linker to use. \"gold\" is the default linker when using gcc\n"); + printf(" --linker=linker The linker to use. \"lld\" or \"gold\" is the default linker when using gcc\n"); if(run) { printf(" --args A list of arguments to run the program with\n"); } else { @@ -182,7 +182,7 @@ static void usageTest() printf(" --sanitize=option Add runtime address/undefined behavior sanitization. Program can be up to 3 times slower and use 10 times as much RAM. Ignored if compiler doesn't support sanitization - Optional (default: address)\n"); printf(" --file Specify file to test, path to test file should be defined after this. Can be defined multiple times to test multiple files - Optional (default: not used), Only applicable for Zig\n"); printf(" --all-files Test all files - Optional (default: not used), Only applicable for Zig\n"); - printf(" --linker=linker The linker to use. \"gold\" is the default linker when using gcc\n"); + printf(" --linker=linker The linker to use. \"lld\" or \"gold\" is the default linker when using gcc\n"); printf(" --skip-compile Skip compilation. This can be used to generate a compile_commands.json file without compiling. Note that the compile_commands.json can miss files that are generated when this option is used. This option also skips running the tests\n"); printf(" --args A list of arguments to run the program with\n"); printf("Examples:\n"); @@ -664,6 +664,14 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run) Compiler compiler = Compiler::MSVC; #endif + // TODO: Make mold the default linker if it's installed and the installed gcc version supports it with -fuse-ld= option + if(linker.empty()) { + if(is_lld_linker_installed()) + linker = "lld"; + else if(is_gold_linker_installed()) + linker = "gold"; + } + SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, false); sibsConfig.showWarnings = true; sibsConfig.platform = platform; -- cgit v1.2.3