From d20ab1b390c14ac794ca3438df7e1d9cf057ceed Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 8 Mar 2022 16:09:37 +0100 Subject: Add --linker, --build and --skip-compile options --- backend/BackendUtils.cpp | 2 ++ backend/ninja/Ninja.cpp | 20 +++++++++++---- include/Conf.hpp | 8 ++++-- src/CmakeModule.cpp | 20 +++++++++------ src/main.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 97 insertions(+), 18 deletions(-) diff --git a/backend/BackendUtils.cpp b/backend/BackendUtils.cpp index befd7ed..caeea3c 100644 --- a/backend/BackendUtils.cpp +++ b/backend/BackendUtils.cpp @@ -116,6 +116,8 @@ namespace backend subProjectConfig->packaging = sibsConfig.packaging; subProjectConfig->platform = sibsConfig.platform; subProjectConfig->bundling = sibsConfig.bundling; + subProjectConfig->linker = sibsConfig.linker; + subProjectConfig->skipCompile = sibsConfig.skipCompile; FileString subProjectBuildPath; readSibsConfig(file->path, projectConfPath, *subProjectConfig, subProjectBuildPath); diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index be8e303..7c0e9c0 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -809,6 +809,10 @@ namespace backend // TODO: Allow configuring default linking flags. Maybe have `package.useThreads = false` to disable this flag string allLinkerFlags; + + if(!config.linker.empty()) + allLinkerFlags += " -fuse-ld=" + config.linker; + if(isSamePlatformFamily(config.platform, PLATFORM_LINUX)) allLinkerFlags = "-pthread"; @@ -1703,13 +1707,15 @@ namespace backend if (fileOverwriteResult.isErr()) return fileOverwriteResult; - Result buildResult = compile(savePath); - if (!buildResult) - return buildResult; + if(config.skipCompile) { + Result buildResult = compile(savePath); + if (!buildResult) + return buildResult; + } if((config.isMainProject() && !config.shouldBuildTests()) || config.isTest()) { - buildResult = buildCompilationDatabase(savePath, config.getProjectPath()); + Result buildResult = buildCompilationDatabase(savePath, config.getProjectPath()); if(!buildResult) return buildResult; } @@ -1750,6 +1756,10 @@ namespace backend sibsTestConfig.setSanitize(config.getSanitize()); sibsTestConfig.zigTestFiles = move(config.zigTestFiles); sibsTestConfig.zigTestAllFiles = config.zigTestAllFiles; + sibsTestConfig.cVersion = config.cVersion; + sibsTestConfig.cppVersion = config.cppVersion; + sibsTestConfig.linker = config.linker; + sibsTestConfig.skipCompile = config.skipCompile; if(projectConfFileType == FileType::REGULAR) { Result result = Config::readFromFile(projectConfFilePath.data.c_str(), sibsTestConfig); @@ -1831,7 +1841,7 @@ namespace backend if (!buildFileResult) return buildFileResult; - if(!zigTest) + if(!zigTest && !config.testsBuildOnly) { Result runTestResult = exec({ Path(buildPath).join(toFileString(sibsTestConfig.getPackageName())).data }, true); if(!runTestResult) diff --git a/include/Conf.hpp b/include/Conf.hpp index cbb21ca..673a7f6 100644 --- a/include/Conf.hpp +++ b/include/Conf.hpp @@ -438,6 +438,12 @@ namespace sibs std::vector exposeIncludeDirs; std::vector ignoreDirs; std::vector libs; + + CVersion cVersion; + CPPVersion cppVersion; + std::string linker; + bool testsBuildOnly = false; + bool skipCompile = false; protected: virtual void processObject(StringView name) override; virtual void processField(StringView name, const ConfigValue &value) override; @@ -474,8 +480,6 @@ namespace sibs std::vector cmakeArgsGlobal; std::vector cmakeArgsStatic; std::vector cmakeArgsDynamic; - CVersion cVersion; - CPPVersion cppVersion; bool useCmake; bool buildTests; bool finishedProcessing; diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp index a706e64..65e0c92 100644 --- a/src/CmakeModule.cpp +++ b/src/CmakeModule.cpp @@ -194,6 +194,7 @@ namespace sibs _putenv("CXXFLAGS=-fPIC"); #endif #endif + std::vector cmd = { cmakePath }; FileString cflags = TINYDIR_STRING("-fPIC"); @@ -238,6 +239,9 @@ namespace sibs } } + if(!config.linker.empty()) + cflags += TINYDIR_STRING(" -fuse-ld=") + toFileString(config.linker); + cxxflags = cflags; cmd.push_back(TINYDIR_STRING("-DCMAKE_C_FLAGS=") + cflags); cmd.push_back(TINYDIR_STRING("-DCMAKE_CXX_FLAGS=") + cxxflags); @@ -299,14 +303,16 @@ namespace sibs return Result::Err(execResult); //nprintf("Compiling cmake generated ninja file: %s\n", buildPath.c_str()); - execResult = exec({ TINYDIR_STRING("ninja"), TINYDIR_STRING("-C"), buildPath }, true); - if(execResult.isOk()) - { - if(execResult.unwrap().exitCode != 0) - return Result::Err(execResult.unwrap().execStdout); + if(config.skipCompile) { + execResult = exec({ TINYDIR_STRING("ninja"), TINYDIR_STRING("-C"), buildPath }, true); + if(execResult.isOk()) + { + if(execResult.unwrap().exitCode != 0) + return Result::Err(execResult.unwrap().execStdout); + } + else + return Result::Err(execResult); } - else - return Result::Err(execResult); if(config.getPackageType() != PackageType::EXECUTABLE) { diff --git a/src/main.cpp b/src/main.cpp index 7c0707d..0caaf22 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -129,15 +129,19 @@ static void usage() static void usageBuild(bool run) { - printf("Usage: sibs %s [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--platform ]\n\n", run ? "run" : "build"); + printf("Usage: sibs %s [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=linker] [--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"); printf(" --debug|--release Optimization level to build project and dependencies with (if not a system package) - Optional (default: --debug)\n"); - printf(" --sanitize 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(" --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(" --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"); + if(!run) { + 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\n"); + } printf("Examples:\n"); printf(" sibs %s\n", run ? "run" : "build"); if(run) @@ -167,14 +171,17 @@ static void usageNew() static void usageTest() { - printf("Usage: sibs test [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--file ...|--all-files]\n\n"); + printf("Usage: sibs test [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=linker] [--file ...|--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"); printf(" --debug|--release Optimization level to build project and dependencies with (if not a system package) - Optional (default: --debug)\n"); - printf(" --sanitize 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(" --build|-b Build tests but don't run them\n"); + 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(" --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("Examples:\n"); printf(" sibs test\n"); printf(" sibs test dirA/dirB\n"); @@ -498,9 +505,11 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run) OptimizationLevel optimizationLevel = OPT_LEV_NONE; FileString projectPath; Sanitize sanitize = Sanitize::NONE; + std::string linker; FileString platformName; bool use_lto = false; bool include_debug_symbols_in_release = false; + bool skipCompile = false; std::vector run_args; for(int i = 0; i < argc; ++i) @@ -534,12 +543,29 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run) } else if(_tinydir_strncmp(arg, TINYDIR_STRING("--sanitize="), 11) == 0) { + if(sanitize != Sanitize::NONE) { + ferr << "Error: Sanitize defined more than once" << endl; + usageBuild(run); + } + sanitize = sanitize_string_to_type(arg + 11); if(sanitize == SANITIZE_INVALID) { ferr << "Error: Invalid sanitize option " << (arg + 11) << ", expected address, undefined, leak, thread or none" << endl; usageBuild(run); } } + else if(_tinydir_strncmp(arg, TINYDIR_STRING("--linker="), 9) == 0) + { + if(!linker.empty()) { + ferr << "Error: Linker defined more than once" << endl; + usageBuild(run); + } + linker = toUtf8(arg + 9); + } + else if(!run && _tinydir_strcmp(arg, TINYDIR_STRING("--skip-compile")) == 0) + { + skipCompile = true; + } else if(_tinydir_strcmp(arg, TINYDIR_STRING("--platform")) == 0) { if(i == argc - 1) @@ -639,7 +665,9 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run) sibsConfig.showWarnings = true; sibsConfig.platform = platform; sibsConfig.setSanitize(sanitize); + sibsConfig.linker = std::move(linker); sibsConfig.use_lto = use_lto; + sibsConfig.skipCompile = skipCompile; sibsConfig.include_debug_symbols_in_release = include_debug_symbols_in_release; return buildProject(projectPath, projectConfFilePath, sibsConfig, run, run_args); } @@ -651,6 +679,10 @@ static int testProject(int argc, const _tinydir_char_t **argv) vector filesToTest; bool testAllFiles = false; Sanitize sanitize = Sanitize::ADDRESS; + bool sanitize_defined = false; + bool buildOnly = false; + bool skipCompile = false; + std::string linker; for(int i = 0; i < argc; ++i) { @@ -675,12 +707,34 @@ static int testProject(int argc, const _tinydir_char_t **argv) } else if(_tinydir_strncmp(arg, TINYDIR_STRING("--sanitize="), 11) == 0) { + if(sanitize_defined) { + ferr << "Error: Sanitize defined more than once" << endl; + usageTest(); + } + + sanitize_defined = true; sanitize = sanitize_string_to_type(arg + 11); if(sanitize == SANITIZE_INVALID) { ferr << "Error: Invalid sanitize option " << (arg + 11) << ", expected address, undefined, leak, thread or none" << endl; usageTest(); } } + else if(_tinydir_strncmp(arg, TINYDIR_STRING("--linker="), 9) == 0) + { + if(!linker.empty()) { + ferr << "Error: Linker defined more than once" << endl; + usageTest(); + } + linker = toUtf8(arg + 9); + } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("--build")) == 0 || _tinydir_strcmp(arg, TINYDIR_STRING("-b")) == 0) + { + buildOnly = true; + } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("--skip-compile")) == 0) + { + skipCompile = true; + } else if(_tinydir_strcmp(arg, TINYDIR_STRING("--file")) == 0) { if(i == argc - 1) @@ -802,8 +856,11 @@ static int testProject(int argc, const _tinydir_char_t **argv) SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, true); sibsConfig.showWarnings = true; sibsConfig.setSanitize(sanitize); + sibsConfig.linker =std::move(linker); sibsConfig.zigTestFiles = move(filesToTest); sibsConfig.zigTestAllFiles = testAllFiles; + sibsConfig.testsBuildOnly = buildOnly; + sibsConfig.skipCompile = skipCompile; return buildProject(projectPath, projectConfFilePath, sibsConfig, false, {}); } -- cgit v1.2.3