aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-28 16:57:06 +0100
committerdec05eba <dec05eba@protonmail.com>2017-12-28 16:57:11 +0100
commit1f583ebb6e3973c992d59886659bf53ff87f41de (patch)
treecfefa98bf921d443f577785d744a5fe6d12f2e86
parentda405ce0c1c9c675aee1710917d9d89b7eb34922 (diff)
Add optimization level option to building
-rw-r--r--backend/ninja/Ninja.cpp22
-rw-r--r--backend/ninja/Ninja.hpp2
-rw-r--r--include/Conf.hpp17
-rw-r--r--include/GlobalLib.hpp3
-rw-r--r--src/Conf.cpp10
-rw-r--r--src/GlobalLib.cpp22
-rw-r--r--src/main.cpp80
7 files changed, 131 insertions, 25 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 3c2b848..ddc20dd 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -121,8 +121,9 @@ namespace backend
// TODO: First check if pkg-config is installed. If it's not, only check dependencies that exists in the dependencies sub directory.
// If pkg-config is installed and dependency is not installed, check in dependencies sub directory.
- Result<bool> Ninja::getLinkerFlags(const vector<Dependency> &dependencies, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const
+ Result<bool> Ninja::getLinkerFlags(const SibsConfig &config, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const
{
+ const vector<Dependency> &dependencies = config.getDependencies();
if(dependencies.empty()) return Result<bool>::Ok(true);
string globalLibDir = getHomeDir();
@@ -166,7 +167,7 @@ namespace backend
for(const Dependency &globalLibDependency : globalLibDependencies)
{
printf("Dependency %s is missing from pkg-config, trying global lib\n", globalLibDependency.name.c_str());
- Result<string> globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
+ Result<string> globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(config, globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
if(globalLibLinkerFlagsResult.isErr())
{
if(globalLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_NOT_FOUND || globalLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_VERSION_NO_MATCH)
@@ -185,7 +186,7 @@ namespace backend
if(downloadDependencyResult.isErr())
return downloadDependencyResult;
- globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
+ globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(config, globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
if(globalLibLinkerFlagsResult.isErr())
return Result<bool>::Err(globalLibLinkerFlagsResult);
}
@@ -271,6 +272,17 @@ namespace backend
return Result<bool>::Err("Unexpected error");
}
+ string optimizationFlags;
+ switch(config.getOptimizationLevel())
+ {
+ case OPT_LEV_DEBUG:
+ optimizationFlags = "'-O0'";
+ break;
+ case OPT_LEV_RELEASE:
+ optimizationFlags = "'-O3' '-DNDEBUG'";
+ break;
+ }
+
vector<string> objectNames;
objectNames.reserve(sourceFiles.size());
for(const string &sourceFile : sourceFiles)
@@ -283,7 +295,7 @@ namespace backend
result += ": cpp_COMPILER ../../";
result += sourceFile;
result += "\n";
- result += " ARGS = $globalIncDir '-I" + config.getPackageName() + "@exe' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-O0' '-g'\n\n";
+ result += " ARGS = $globalIncDir '-I" + config.getPackageName() + "@exe' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' " + optimizationFlags + " '-g'\n\n";
objectNames.emplace_back(objectName);
}
@@ -314,7 +326,7 @@ namespace backend
allLinkerFlags += linkerFlag;
};
- Result<bool> linkerFlags = getLinkerFlags(config.getDependencies(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
+ Result<bool> linkerFlags = getLinkerFlags(config, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
if(linkerFlags.isErr())
return Result<bool>::Err(linkerFlags.getErrMsg());
diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp
index ea73c81..fddcaf3 100644
--- a/backend/ninja/Ninja.hpp
+++ b/backend/ninja/Ninja.hpp
@@ -34,7 +34,7 @@ namespace backend
bool containsSourceFile(const std::string &filepath) const;
bool containsTestSourceDir(const std::string &dir) const;
bool containsDependency(const std::string &dependency) const;
- sibs::Result<bool> getLinkerFlags(const std::vector<sibs::Dependency> &dependencies, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const;
+ sibs::Result<bool> getLinkerFlags(const sibs::SibsConfig &config, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const;
sibs::Result<bool> build(const char *buildFilePath);
private:
std::vector<std::string> sourceFiles;
diff --git a/include/Conf.hpp b/include/Conf.hpp
index b893d3a..1f680e8 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -84,10 +84,19 @@ namespace sibs
static Result<bool> readFromFile(const char *filepath, const ConfigCallback &callback);
};
+ enum OptimizationLevel
+ {
+ OPT_LEV_NONE,
+ OPT_LEV_DEBUG,
+ OPT_LEV_RELEASE
+ };
+
+ const char* asString(OptimizationLevel optLevel);
+
class SibsConfig : public ConfigCallback
{
public:
- SibsConfig(const std::string &_projectPath) : projectPath(_projectPath), finishedProcessing(false), packageType((PackageType)-1) {}
+ SibsConfig(const std::string &_projectPath, OptimizationLevel _optimizationLevel = OPT_LEV_DEBUG) : projectPath(_projectPath), packageType((PackageType)-1), optimizationLevel(_optimizationLevel), finishedProcessing(false) {}
virtual ~SibsConfig(){}
virtual const std::string& getPackageName() const
@@ -121,6 +130,11 @@ namespace sibs
{
return includeDirs;
}
+
+ virtual OptimizationLevel getOptimizationLevel() const
+ {
+ return optimizationLevel;
+ }
protected:
virtual void processObject(StringView name) override;
virtual void processField(StringView name, const ConfigValue &value) override;
@@ -133,6 +147,7 @@ namespace sibs
PackageType packageType;
std::vector<Dependency> dependencies;
std::vector<std::string> includeDirs;
+ OptimizationLevel optimizationLevel;
bool finishedProcessing;
};
diff --git a/include/GlobalLib.hpp b/include/GlobalLib.hpp
index 78511c3..c67027e 100644
--- a/include/GlobalLib.hpp
+++ b/include/GlobalLib.hpp
@@ -4,6 +4,7 @@
#include "Result.hpp"
#include "Linker.hpp"
#include "Dependency.hpp"
+#include "Conf.hpp"
namespace sibs
{
@@ -17,7 +18,7 @@ namespace sibs
};
static Result<bool> validatePackageExists(const std::string &globalLibRootDir, const std::string &name);
- static Result<std::string> getLibsLinkerFlags(const std::string &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc);
+ static Result<std::string> getLibsLinkerFlags(const SibsConfig &parentConfig, const std::string &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc);
static Result<bool> downloadDependency(const Dependency &dependency);
};
}
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 97d562c..d6aee2c 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -332,6 +332,16 @@ namespace sibs
return Parser::parse(code, callback);
}
+ const char* asString(OptimizationLevel optLevel)
+ {
+ switch(optLevel)
+ {
+ case OPT_LEV_NONE: return "none";
+ case OPT_LEV_DEBUG: return "debug";
+ case OPT_LEV_RELEASE: return "release";
+ }
+ }
+
void SibsConfig::processObject(StringView name)
{
currentObject = name;
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index 30a044f..d994a27 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -60,7 +60,7 @@ namespace sibs
return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0;
}
- Result<string> GlobalLib::getLibsLinkerFlags(const string &globalLibRootDir, const string &name, const string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc)
+ Result<string> GlobalLib::getLibsLinkerFlags(const SibsConfig &parentConfig, const string &globalLibRootDir, const string &name, const string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc)
{
Result<bool> packageExistsResult = validatePackageExists(globalLibRootDir, name);
if(packageExistsResult.isErr())
@@ -110,7 +110,7 @@ namespace sibs
}
}
- SibsConfig sibsConfig(packageDir);
+ SibsConfig sibsConfig(packageDir, parentConfig.getOptimizationLevel());
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if(result.isErr())
return Result<string>::Err(result.getErrMsg());
@@ -175,8 +175,18 @@ namespace sibs
}
else
{
- string debugBuildPath = packageDir + "/sibs-build/debug";
- string libPath = debugBuildPath;
+ string buildPath = packageDir + "/sibs-build/";
+ switch(sibsConfig.getOptimizationLevel())
+ {
+ case OPT_LEV_DEBUG:
+ buildPath += "debug";
+ break;
+ case OPT_LEV_RELEASE:
+ buildPath += "release";
+ break;
+ }
+
+ string libPath = buildPath;
libPath += "/lib";
libPath += name;
if(libraryType == backend::Ninja::LibraryType::STATIC)
@@ -199,11 +209,11 @@ namespace sibs
// TODO: Use different directories depending on the project type, but .o build files should be in the same directory
// no matter what project type, since they are used for executables, static/dynamic libraries
- Result<bool> createBuildDirResult = createDirectoryRecursive(debugBuildPath.c_str());
+ Result<bool> createBuildDirResult = createDirectoryRecursive(buildPath.c_str());
if(createBuildDirResult.isErr())
return Result<string>::Err(createBuildDirResult);
- Result<bool> buildFileResult = ninja.build(sibsConfig, debugBuildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc);
+ Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc);
if (buildFileResult.isErr())
return Result<string>::Err(buildFileResult.getErrMsg());
diff --git a/src/main.cpp b/src/main.cpp
index 79d4d9d..0f20ea0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,6 +30,21 @@ void usage()
exit(1);
}
+void usageBuild()
+{
+ printf("Usage: sibs build [project_path] [--debug|--release]\n\n");
+ printf("Build a sibs project\n\n");
+ printf("Options:\n");
+ printf(" project_path\t\t The directory containing a project.conf file - Optional (default: current working directory)\n");
+ printf(" --debug|--release\t\tOptimization level to build project and dependencies with (if not a system package) - Optional (default: --debug)\n");
+ printf("Examples:\n");
+ printf(" sibs build\n");
+ printf(" sibs build dirA/dirB\n");
+ printf(" sibs build --release\n");
+ printf(" sibs build dirA --release\n");
+ exit(1);
+}
+
void usageNew()
{
printf("Usage: sibs new <project_name> <--exec|--static|--dynamic>\n\n");
@@ -100,17 +115,50 @@ bool isPathSubPathOf(const string &path, const string &subPathOf)
int buildProject(int argc, const char **argv)
{
- if(argc > 1)
+ if(argc > 2)
+ usageBuild();
+
+ OptimizationLevel optimizationLevel = OPT_LEV_NONE;
+ string projectPath;
+
+ for(int i = 0; i < argc; ++i)
{
- cerr << "Expected 'build' command to only be followed by one argument which is the path to a directory that contains a project.conf file, ";
- cerr << "or none; in which case build would use the working directory as target directory" << endl << endl;
- usage();
+ const char *arg = argv[i];
+ if(strcmp(arg, "--debug") == 0)
+ {
+ if(optimizationLevel != OPT_LEV_NONE)
+ {
+ fprintf(stderr, "Error: Optimization level defined more than once. First defined as %s then as %s\n", asString(optimizationLevel), "debug");
+ usageBuild();
+ }
+ optimizationLevel = OPT_LEV_DEBUG;
+ }
+ else if(strcmp(arg, "--release") == 0)
+ {
+ if(optimizationLevel != OPT_LEV_NONE)
+ {
+ fprintf(stderr, "Error: Optimization level defined more than once. First defined as %s then as %s\n", asString(optimizationLevel), "debug");
+ usageBuild();
+ }
+ optimizationLevel = OPT_LEV_RELEASE;
+ }
+ else
+ {
+ if(!projectPath.empty())
+ {
+ fprintf(stderr, "Error: Project path was defined more than once. First defined as %s then as %s\n", projectPath.c_str(), arg);
+ usageBuild();
+ }
+ projectPath = arg;
+ }
}
- // TODO: If argc == 0 and working directory does not contain project.conf, then search every parent directory until one is found
- string projectPath = ".";
- if(argc == 1)
- projectPath = argv[0];
+ if(optimizationLevel == OPT_LEV_NONE)
+ optimizationLevel = OPT_LEV_DEBUG;
+
+ // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found
+ if(projectPath.empty())
+ projectPath = ".";
validateDirectoryPath(projectPath.c_str());
if(projectPath.back() != '/')
@@ -128,7 +176,7 @@ int buildProject(int argc, const char **argv)
projectConfFilePath += "/project.conf";
validateFilePath(projectConfFilePath.c_str());
- SibsConfig sibsConfig(projectPath);
+ SibsConfig sibsConfig(projectPath, optimizationLevel);
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if(result.isErr())
{
@@ -186,8 +234,18 @@ int buildProject(int argc, const char **argv)
};
walkDir(projectPath.c_str(), collectSourceFiles);
- string debugBuildPath = projectPath + "/sibs-build/debug";
- Result<bool> buildFileResult = ninja.build(sibsConfig, debugBuildPath.c_str());
+ string buildPath = projectPath + "/sibs-build/";
+ switch(sibsConfig.getOptimizationLevel())
+ {
+ case OPT_LEV_DEBUG:
+ buildPath += "debug";
+ break;
+ case OPT_LEV_RELEASE:
+ buildPath += "release";
+ break;
+ }
+
+ Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str());
if(buildFileResult.isErr())
{
cerr << "Failed to build ninja file: " << buildFileResult.getErrMsg() << endl;