aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-03-08 12:53:25 +0100
committerdec05eba <dec05eba@protonmail.com>2023-03-08 12:53:25 +0100
commit0697f410b05085cdaf767d5b6fd3fea056ec5bd3 (patch)
tree09c5a5c920b191edb0ceffe30ae0cc99de91b11d
parentcc0eb4651e4b204fb7926ddd84bb830f432aabd3 (diff)
Add support for mold, add optimization flags for linking step
-rw-r--r--README.md2
-rw-r--r--backend/ninja/Ninja.cpp12
-rw-r--r--include/FileUtil.hpp1
-rw-r--r--include/Linker.hpp1
-rw-r--r--src/CmakeModule.cpp4
-rw-r--r--src/FileUtil.cpp10
-rw-r--r--src/Linker.cpp4
-rw-r--r--src/main.cpp22
8 files changed, 45 insertions, 11 deletions
diff --git a/README.md b/README.md
index b26a472..c2661c2 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,7 @@ The current recommended way of using sibs is to add dependencies as git submodul
You can list all your system packages with `pkg-config --list-all` (if the packages provide pkg-config files). To search for a package in this list you can use grep, like so: `pkg-config --list-all | grep 'pkg-name'` (replace pkg-name with the name of the package you want to search for).\
To then show the version of the found package you can use `pkg-config --modversion pkg-name`.
-sibs will prefer lld linker in release mode if it's available and then the gold linker. You can install lld to improve compile times. Note that gdb debugging is a bit buggy when using lld so use of lld is only recommended in release mode.
+sibs will prefer mold linker in release mode if it's available and then the lld linker and then the gold linker. You can install mold/lld to improve compile times. Note that gdb debugging is a bit buggy when using mold/lld so use of mold/lld is only recommended in release mode.
# Quirks
Zig support has not been tested properly yet and currently always links to c library.
You can run zig tests with `sibs test --file filepath` or `sibs test --all-files`.
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 6c69d13..c66907c 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -810,7 +810,9 @@ namespace backend
// TODO: Allow configuring default linking flags. Maybe have `package.useThreads = false` to disable this flag
string allLinkerFlags;
- if(!config.linker.empty())
+ if(config.linker == "mold")
+ allLinkerFlags += " -B/usr/lib/mold/";
+ else if(!config.linker.empty())
allLinkerFlags += " -fuse-ld=" + config.linker;
if(isSamePlatformFamily(config.platform, PLATFORM_POSIX))
@@ -1011,6 +1013,10 @@ namespace backend
vector<ninja::NinjaArg> optimizationFlags = getCompilerOptimizationFlags(config);
compileCCommand.insert(compileCCommand.end(), optimizationFlags.begin(), optimizationFlags.end());
+ for(auto &optFlag : optimizationFlags) {
+ allLinkerFlags += " " + optFlag.arg;
+ }
+
ninja::NinjaArg sanitizerFlag = getCompilerSanitizerFlag(config);
if(sanitizerFlag.type != ninja::NinjaArg::Type::NONE)
compileCCommand.push_back(std::move(sanitizerFlag));
@@ -1065,6 +1071,10 @@ namespace backend
vector<ninja::NinjaArg> optimizationFlags = getCompilerOptimizationFlags(config);
compileCCommand.insert(compileCCommand.end(), optimizationFlags.begin(), optimizationFlags.end());
+ for(auto &optFlag : optimizationFlags) {
+ allLinkerFlags += " " + optFlag.arg;
+ }
+
ninja::NinjaArg sanitizerFlag = getCompilerSanitizerFlag(config);
if(sanitizerFlag.type != ninja::NinjaArg::Type::NONE)
compileCCommand.push_back(std::move(sanitizerFlag));
diff --git a/include/FileUtil.hpp b/include/FileUtil.hpp
index 5bd4d33..2b4f3c5 100644
--- a/include/FileUtil.hpp
+++ b/include/FileUtil.hpp
@@ -81,6 +81,7 @@ namespace sibs
};
FileType getFileType(const _tinydir_char_t *path);
+ bool fileExists(const _tinydir_char_t *path);
void walkDir(const _tinydir_char_t *directory, FileWalkCallbackFunc callbackFunc);
void walkDirFiles(const _tinydir_char_t *directory, FileWalkCallbackFunc callbackFunc);
bool walkDirFilesRecursive(const _tinydir_char_t *directory, FileWalkCallbackFunc callbackFunc);
diff --git a/include/Linker.hpp b/include/Linker.hpp
index b2e64fe..59e39b3 100644
--- a/include/Linker.hpp
+++ b/include/Linker.hpp
@@ -12,6 +12,7 @@ namespace sibs
bool is_gold_linker_installed();
bool is_lld_linker_installed();
+ bool is_mold_linker_installed();
}
#endif //SIBS_LINKER_HPP
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp
index e3b3918..063cced 100644
--- a/src/CmakeModule.cpp
+++ b/src/CmakeModule.cpp
@@ -239,7 +239,9 @@ namespace sibs
}
}
- if(!config.linker.empty())
+ if(config.linker == "mold")
+ cflags += TINYDIR_STRING(" -B/usr/lib/mold/");
+ else if(!config.linker.empty())
cflags += TINYDIR_STRING(" -fuse-ld=") + toFileString(config.linker);
cxxflags = cflags;
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp
index e1142ec..02acfa4 100644
--- a/src/FileUtil.cpp
+++ b/src/FileUtil.cpp
@@ -141,6 +141,11 @@ namespace sibs
else
return FileType::FILE_NOT_FOUND;
}
+
+ bool fileExists(const _tinydir_char_t *path) {
+ struct stat64 fileStat;
+ return stat64(path, &fileStat) == 0;
+ }
Result<u64> getFileLastModifiedTime(const _tinydir_char_t *path)
{
@@ -163,6 +168,11 @@ namespace sibs
else
return FileType::FILE_NOT_FOUND;
}
+
+ bool fileExists(const _tinydir_char_t *path) {
+ struct _stat64i32 fileStat;
+ return _wstat(path, &fileStat) == 0;
+ }
Result<u64> getFileLastModifiedTime(const _tinydir_char_t *path)
{
diff --git a/src/Linker.cpp b/src/Linker.cpp
index 1546909..d03e3a4 100644
--- a/src/Linker.cpp
+++ b/src/Linker.cpp
@@ -46,4 +46,8 @@ namespace sibs
bool is_lld_linker_installed() {
return is_linker_installed("ld.lld");
}
+
+ bool is_mold_linker_installed() {
+ return is_linker_installed("ld.mold") && fileExists("/usr/lib/mold/ld");
+ }
} \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index c67ac68..aa06549 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -129,7 +129,7 @@ static void usage()
static void usageBuild(bool run)
{
- printf("Usage: sibs %s [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=linker] [--platform <platform>]\n\n", run ? "run" : "build");
+ printf("Usage: sibs %s [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=lld|gold|mold] [--platform <platform>]\n\n", run ? "run" : "build");
printf("%s a sibs project\n\n", run ? "Build and run" : "Build");
printf("Options:\n");
printf(" project_path The directory containing a project.conf file - Optional (default: current directory)\n");
@@ -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. \"lld\" or \"gold\" is the default linker when using gcc\n");
+ printf(" --linker=linker The linker to use. \"lld\", \"gold\" or \"mold\". \"gold\" - Optional (the compile automatically chooses best option)\n");
if(run) {
printf(" --args <args...> A list of arguments to run the program with\n");
} else {
@@ -173,7 +173,7 @@ static void usageNew()
static void usageTest()
{
- printf("Usage: sibs test [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=linker] [--file <filepath>...|--all-files]\n\n");
+ printf("Usage: sibs test [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=lld|gold|mold] [--file <filepath>...|--all-files]\n\n");
printf("Build and run tests for a sibs project\n\n");
printf("Options:\n");
printf(" project_path The directory containing a project.conf file - Optional (default: current directory)\n");
@@ -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: none)\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. \"lld\" or \"gold\" is the default linker when using gcc\n");
+ printf(" --linker=linker The linker to use. \"lld\", \"gold\" or \"mold\". \"gold\" - Optional (the compile automatically chooses best option)\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 <args...> A list of arguments to run the program with\n");
printf("Examples:\n");
@@ -664,16 +664,22 @@ 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()) {
// Static object files compiled with gcc are not compatible with lld (llvm linker)
// and we dont know which compiler was used to compile to code so we disable automatic
// use of lld by default. The user can still force lld with --linker=lld, if they are
// sure that they used clang to compile the code.
- if(!use_lto && optimizationLevel != OPT_LEV_DEBUG && !include_debug_symbols_in_release && is_lld_linker_installed())
- linker = "lld";
- else if(is_gold_linker_installed())
+ // TODO: Detect if linker has change and recompile everything (that was compiled with a different linker).
+ if(!use_lto && optimizationLevel != OPT_LEV_DEBUG && !include_debug_symbols_in_release) {
+ if(is_mold_linker_installed())
+ linker = "mold";
+ else if(is_lld_linker_installed())
+ linker = "lld";
+ else if(is_gold_linker_installed())
+ linker = "gold";
+ } else if(is_gold_linker_installed()) {
linker = "gold";
+ }
}
SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, false);