aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/BackendUtils.cpp2
-rw-r--r--backend/ninja/Ninja.cpp42
-rw-r--r--include/Conf.hpp8
-rw-r--r--src/CmakeModule.cpp13
-rw-r--r--src/GlobalLib.cpp1
-rw-r--r--src/main.cpp51
6 files changed, 103 insertions, 14 deletions
diff --git a/backend/BackendUtils.cpp b/backend/BackendUtils.cpp
index caeea3c..1109bf1 100644
--- a/backend/BackendUtils.cpp
+++ b/backend/BackendUtils.cpp
@@ -113,6 +113,8 @@ namespace backend
backend::Ninja *subProject = new backend::Ninja();
SibsConfig *subProjectConfig = new SibsConfig(sibsConfig.getCompiler(), file->path, sibsConfig.getOptimizationLevel(), false);
+ subProjectConfig->setSanitize(sibsConfig.getSanitize());
+ subProjectConfig->cpu = sibsConfig.cpu;
subProjectConfig->packaging = sibsConfig.packaging;
subProjectConfig->platform = sibsConfig.platform;
subProjectConfig->bundling = sibsConfig.bundling;
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index c66907c..802ffd8 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -379,6 +379,37 @@ namespace backend
return {};
}
+ static ninja::NinjaArg getCompilerCpuFlag(const SibsConfig &config)
+ {
+ // TODO: Also use -mcpu=native on non x86 systems
+ switch(config.getCompiler()) {
+ case Compiler::GCC:
+ case Compiler::MINGW_W64: {
+ switch(config.cpu) {
+ case sibs::CPU_INVALID:
+ case sibs::CPU_BASELINE:
+ return {};
+ case sibs::CPU_NATIVE:
+ return ninja::NinjaArg::createRaw("-march=native");
+ }
+ break;
+ }
+ case Compiler::MSVC: {
+ // msvc doesn't have any equivalent to gcc -march=native.
+ // TODO: Detect features at runtime here to manually add the cpu feature flags instead
+ switch(config.cpu) {
+ case sibs::CPU_INVALID:
+ case sibs::CPU_BASELINE:
+ return {};
+ case sibs::CPU_NATIVE:
+ return ninja::NinjaArg::createRaw("-march=native");
+ }
+ break;
+ }
+ }
+ return {};
+ }
+
static vector<ninja::NinjaArg> getCompilerOptimizationFlags(const SibsConfig &config)
{
switch (config.getCompiler())
@@ -1017,6 +1048,10 @@ namespace backend
allLinkerFlags += " " + optFlag.arg;
}
+ ninja::NinjaArg cpuFlag = getCompilerCpuFlag(config);
+ if(cpuFlag.type != ninja::NinjaArg::Type::NONE)
+ compileCCommand.push_back(std::move(cpuFlag));
+
ninja::NinjaArg sanitizerFlag = getCompilerSanitizerFlag(config);
if(sanitizerFlag.type != ninja::NinjaArg::Type::NONE)
compileCCommand.push_back(std::move(sanitizerFlag));
@@ -1075,6 +1110,10 @@ namespace backend
allLinkerFlags += " " + optFlag.arg;
}
+ ninja::NinjaArg cpuFlag = getCompilerCpuFlag(config);
+ if(cpuFlag.type != ninja::NinjaArg::Type::NONE)
+ compileCCommand.push_back(std::move(cpuFlag));
+
ninja::NinjaArg sanitizerFlag = getCompilerSanitizerFlag(config);
if(sanitizerFlag.type != ninja::NinjaArg::Type::NONE)
compileCCommand.push_back(std::move(sanitizerFlag));
@@ -1764,7 +1803,8 @@ namespace backend
SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative.data, config.getOptimizationLevel());
sibsTestConfig.platform = config.platform;
sibsTestConfig.setSanitize(config.getSanitize());
- sibsTestConfig.zigTestFiles = move(config.zigTestFiles);
+ sibsTestConfig.cpu = config.cpu;
+ sibsTestConfig.zigTestFiles = config.zigTestFiles;
sibsTestConfig.zigTestAllFiles = config.zigTestAllFiles;
sibsTestConfig.cVersion = config.cVersion;
sibsTestConfig.cppVersion = config.cppVersion;
diff --git a/include/Conf.hpp b/include/Conf.hpp
index 54c6b89..13fadcf 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -16,6 +16,13 @@
namespace sibs
{
+ enum CPU
+ {
+ CPU_INVALID,
+ CPU_BASELINE,
+ CPU_NATIVE
+ };
+
class ConfigValue
{
public:
@@ -432,6 +439,7 @@ namespace sibs
std::string versionStr;
PackageVersion version;
Platform platform;
+ CPU cpu = CPU_NATIVE;
bool use_lto;
bool include_debug_symbols_in_release;
std::vector<std::string> includeDirs;
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp
index 063cced..62aaf34 100644
--- a/src/CmakeModule.cpp
+++ b/src/CmakeModule.cpp
@@ -200,6 +200,19 @@ namespace sibs
FileString cflags = TINYDIR_STRING("-fPIC");
FileString cxxflags;
+ // TODO: msvc
+ if(config.getCompiler() == Compiler::GCC || config.getCompiler() == Compiler::MINGW_W64)
+ {
+ switch(config.cpu) {
+ case sibs::CPU_INVALID:
+ case sibs::CPU_BASELINE:
+ break;
+ case sibs::CPU_NATIVE:
+ cflags += TINYDIR_STRING(" -march=native");
+ break;
+ }
+ }
+
if(config.getCompiler() == Compiler::GCC || config.getCompiler() == Compiler::MINGW_W64)
{
cflags += TINYDIR_STRING(" -fno-omit-frame-pointer");
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index dc45e23..94145c1 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -157,6 +157,7 @@ namespace sibs
sibsConfig.packaging = parentConfig.packaging;
sibsConfig.bundling = parentConfig.bundling;
sibsConfig.setSanitize(parentConfig.getSanitize());
+ sibsConfig.cpu = parentConfig.cpu;
sibsConfig.linker = parentConfig.linker;
sibsConfig.use_lto = parentConfig.use_lto;
sibsConfig.skipCompile = parentConfig.skipCompile;
diff --git a/src/main.cpp b/src/main.cpp
index aa06549..0e216b7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -129,16 +129,17 @@ static void usage()
static void usageBuild(bool run)
{
- 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("Usage: sibs %s [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=lld|gold|mold] [--platform=<platform>] [--cpu=cpu]\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=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(" --platform=platform The platform to build for. Run \"sibs platforms\" to see a list of supported platforms - 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\", \"gold\" or \"mold\". \"gold\" - Optional (the compile automatically chooses best option)\n");
+ printf(" --cpu=cpu The cpu to target. Should either be \"baseline\" or \"native\". \"baseline\" means to compile the binary to support a wide range of cpu's in the same architecture while \"native\" means to compile the binary specifically for your cpu, for better performance - Optional (default: native)\n");
if(run) {
printf(" --args <args...> A list of arguments to run the program with\n");
} else {
@@ -173,7 +174,7 @@ static void usageNew()
static void usageTest()
{
- 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("Usage: sibs test [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|thread|none)] [--linker=lld|gold|mold] [--platform=<platform>] [--cpu=cpu] [--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 +183,9 @@ 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(" --platform=platform The platform to build for. Run \"sibs platforms\" to see a list of supported platforms - Optional (default: the running platform)\n");
printf(" --linker=linker The linker to use. \"lld\", \"gold\" or \"mold\". \"gold\" - Optional (the compile automatically chooses best option)\n");
+ printf(" --cpu=cpu The cpu to target. Should either be \"baseline\" or \"native\". \"baseline\" means to compile the binary to support a wide range of cpu's in the same architecture while \"native\" means to compile the binary specifically for your cpu, for better performance - Optional (default: native)\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");
@@ -503,6 +506,15 @@ static Sanitize sanitize_string_to_type(const _tinydir_char_t *str) {
return SANITIZE_INVALID;
}
+static CPU getCpuByName(const std::string &cpuName) {
+ if(cpuName == "baseline")
+ return CPU_BASELINE;
+ else if(cpuName == "native")
+ return CPU_NATIVE;
+ else
+ return CPU_INVALID;
+}
+
static int buildProject(int argc, const _tinydir_char_t **argv, bool run)
{
OptimizationLevel optimizationLevel = OPT_LEV_NONE;
@@ -510,6 +522,7 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run)
Sanitize sanitize = Sanitize::NONE;
std::string linker;
FileString platformName;
+ std::string cpuName;
bool use_lto = false;
bool include_debug_symbols_in_release = false;
bool skipCompile = false;
@@ -569,23 +582,23 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run)
{
skipCompile = true;
}
- else if(_tinydir_strcmp(arg, TINYDIR_STRING("--platform")) == 0)
+ else if(_tinydir_strncmp(arg, TINYDIR_STRING("--platform="), 11) == 0)
{
- if(i == argc - 1)
+ if(!platformName.empty())
{
- ferr << "Error: Expected platform to target after --platform" << endl;
+ ferr << "Error: Platform defined more than once" << endl;
usageBuild(run);
}
-
- ++i;
- arg = argv[i];
-
- if(!platformName.empty())
+ platformName = arg + 11;
+ }
+ else if(_tinydir_strncmp(arg, TINYDIR_STRING("--cpu="), 6) == 0)
+ {
+ if(!cpuName.empty())
{
- ferr << "Error: Platform defined twice. First as " << platformName << " then as " << arg << endl;
+ ferr << "Error: CPU defined more than once" << endl;
usageBuild(run);
}
- platformName = arg;
+ cpuName = toUtf8(arg + 6);
}
else if(run && _tinydir_strcmp(arg, TINYDIR_STRING("--args")) == 0)
{
@@ -614,6 +627,9 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run)
if(platformName.empty())
platformName = toFileString(asString(SYSTEM_PLATFORM));
+ if(cpuName.empty())
+ cpuName = "native";
+
string platformUtf8 = toUtf8(platformName);
Platform platform = getPlatformByName(StringView(platformUtf8.data(), platformUtf8.size()));
if(platform == PLATFORM_INVALID)
@@ -623,6 +639,14 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run)
usageBuild(run);
}
+ CPU cpu = getCpuByName(cpuName);
+ if(cpu == CPU_INVALID)
+ {
+ ferr << "Invalid cpu " << cpuName << endl;
+ ferr << "Expected one of: " << "baseline, cpu" << endl;
+ usageBuild(run);
+ }
+
bool crossCompileLinux64ToWin64 = (SYSTEM_PLATFORM == PLATFORM_LINUX_X86_64 && platform == PLATFORM_WIN64);
if(platform != SYSTEM_PLATFORM && !crossCompileLinux64ToWin64)
{
@@ -685,6 +709,7 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run)
SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, false);
sibsConfig.showWarnings = true;
sibsConfig.platform = platform;
+ sibsConfig.cpu = cpu;
sibsConfig.setSanitize(sanitize);
sibsConfig.linker = std::move(linker);
sibsConfig.use_lto = use_lto;