aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-03-21 14:56:51 +0100
committerdec05eba <dec05eba@protonmail.com>2018-03-21 14:58:31 +0100
commit23117906c571714b0b55caf35cf9f876d1f9fa2e (patch)
tree21574306de1efb6eafd2af48f5188bf9e3550dd8
parentb44ff4ec7d2c2458aab04b5daf79134e5d284f6e (diff)
Add sub projects (should be used with git submodules)
Fix issue where static lib dependencies are not built correctly because their dynamic lib dependencies are not propagated to dependant project
-rw-r--r--.vscode/launch.json2
-rw-r--r--CMakeLists.txt1
-rw-r--r--backend/BackendUtils.cpp85
-rw-r--r--backend/BackendUtils.hpp15
-rw-r--r--backend/ninja/Ninja.cpp88
-rw-r--r--backend/ninja/Ninja.hpp23
-rw-r--r--include/Conf.hpp4
-rw-r--r--src/CmakeModule.cpp13
-rw-r--r--src/Conf.cpp57
-rw-r--r--src/GlobalLib.cpp109
-rw-r--r--src/main.cpp91
11 files changed, 275 insertions, 213 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index dc20432..e91a145 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,7 +10,7 @@
"request": "launch",
"target": "./sibs-build/debug/sibs",
"cwd": "${workspaceRoot}",
- "arguments": "build /home/dec05eba/git/gen-sfml-ui"
+ "arguments": "build /home/dec05eba/git/sfml-ui-flat/depends/gen-sfml-ui"
}
]
} \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e1af36..5324cf7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,6 +6,7 @@ set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES
external/xxhash.c
backend/ninja/Ninja.cpp
+ backend/BackendUtils.cpp
src/main.cpp
src/FileUtil.cpp
src/Conf.cpp
diff --git a/backend/BackendUtils.cpp b/backend/BackendUtils.cpp
new file mode 100644
index 0000000..68794f5
--- /dev/null
+++ b/backend/BackendUtils.cpp
@@ -0,0 +1,85 @@
+#include "BackendUtils.hpp"
+#include "../include/FileUtil.hpp"
+#include "ninja/Ninja.hpp"
+
+using namespace std;
+using namespace sibs;
+
+namespace backend
+{
+ bool isPathSubPathOf(const FileString &path, const FileString &subPathOf)
+ {
+ return _tinydir_strncmp(path.c_str(), subPathOf.c_str(), subPathOf.size()) == 0;
+ }
+
+ const _tinydir_char_t *sourceFileExtensions[] = { TINYDIR_STRING("c"), TINYDIR_STRING("cc"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx"), TINYDIR_STRING("c++") };
+ bool BackendUtils::isSourceFile(tinydir_file *file)
+ {
+ if(!file->is_reg)
+ return false;
+
+ for(const _tinydir_char_t *sourceFileExtension : sourceFileExtensions)
+ {
+ if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ void BackendUtils::collectSourceFiles(const _tinydir_char_t *projectPath, Ninja *ninjaProject, const SibsConfig &sibsConfig)
+ {
+ walkDir(projectPath, [ninjaProject, &sibsConfig](tinydir_file *file)
+ {
+ FileString pathNative = file->path;
+ #if OS_FAMILY == OS_FAMILY_WINDOWS
+ replaceChar(pathNative, L'/', L'\\');
+ #endif
+ if(file->is_reg)
+ {
+ if (isSourceFile(file))
+ {
+ string filePathUtf8 = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size());
+ ninjaProject->addSourceFile(filePathUtf8.c_str());
+ }
+ else
+ {
+ //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
+ }
+ }
+ else
+ {
+ if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath()))
+ {
+ string filePathUtf8 = toUtf8(pathNative.c_str());
+ ninjaProject->addTestSourceDir(filePathUtf8.c_str());
+ }
+ else if(!directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs()))
+ {
+ FileString projectConfPath = file->path;
+ #if OS_FAMILY == OS_FAMILY_WINDOWS
+ projectConfPath += L'\\';
+ #else
+ projectConfPath += '/';
+ #endif
+ projectConfPath += TINYDIR_STRING("project.conf");
+
+ auto projectConfFileType = getFileType(projectConfPath.c_str());
+ if(projectConfFileType == FileType::REGULAR)
+ {
+ backend::Ninja *subProject = new backend::Ninja();
+
+ SibsConfig *subProjectConfig = new SibsConfig(sibsConfig.getCompiler(), file->path, sibsConfig.getOptimizationLevel(), false);
+ FileString subProjectBuildPath;
+ readSibsConfig(file->path, projectConfPath, *subProjectConfig, subProjectBuildPath);
+
+ collectSourceFiles(file->path, subProject, *subProjectConfig);
+ ninjaProject->addSubProject(subProject, subProjectConfig, move(subProjectBuildPath));
+ }
+ else
+ collectSourceFiles(file->path, ninjaProject, sibsConfig);
+ }
+ }
+ });
+ }
+}
diff --git a/backend/BackendUtils.hpp b/backend/BackendUtils.hpp
new file mode 100644
index 0000000..b2fe280
--- /dev/null
+++ b/backend/BackendUtils.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "../include/Conf.hpp"
+
+namespace backend
+{
+ class Ninja;
+
+ class BackendUtils
+ {
+ public:
+ static bool isSourceFile(tinydir_file *file);
+ static void collectSourceFiles(const _tinydir_char_t *projectPath, Ninja *ninjaProject, const sibs::SibsConfig &sibsConfig);
+ };
+}
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index fb081de..614d08c 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -1,4 +1,5 @@
#include <cstring>
+#include "../BackendUtils.hpp"
#include "Ninja.hpp"
#include "../../include/FileUtil.hpp"
#include "../../include/Exec.hpp"
@@ -237,6 +238,11 @@ namespace backend
if(!containsDependency(binaryFile))
binaryDependencies.emplace_back(binaryFile);
}
+
+ void Ninja::addSubProject(Ninja *subProject, SibsConfig *config, sibs::FileString &&buildPath)
+ {
+ subProjects.emplace_back(NinjaSubProject{ subProject, config, move(buildPath) });
+ }
const std::vector<std::string>& Ninja::getSourceFiles() const
{
@@ -318,7 +324,7 @@ namespace backend
else
{
const PkgConfigFlags &pkgConfigFlag = pkgConfigFlagsResult.unwrap();
- if (dynamicLinkerFlagCallback && !pkgConfigFlag.linkerFlags.empty())
+ if (!pkgConfigFlag.linkerFlags.empty())
dynamicLinkerFlagCallback(pkgConfigFlag.linkerFlags);
if(!pkgConfigFlag.cflags.empty())
cflagsCallbackFunc(pkgConfigFlag.cflags);
@@ -338,6 +344,26 @@ namespace backend
C,
CPP
};
+
+ Result<bool> Ninja::buildSubProjects(LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
+ {
+ for(auto &subProject : subProjects)
+ {
+ if(subProject.config->getPackageType() == PackageType::EXECUTABLE)
+ {
+ string errMsg = "The sub project ";
+ errMsg += toUtf8(subProject.buildPath);
+ errMsg += " is an executable. Only libraries can be sub projects";
+ return Result<bool>::Err(errMsg);
+ }
+
+ Result<bool> buildResult = subProject.subProject->build(*subProject.config, subProject.buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
+ if(!buildResult)
+ return buildResult;
+ }
+
+ return Result<bool>::Ok(true);
+ }
Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
@@ -405,7 +431,7 @@ namespace backend
#endif
// TODO: Somehow check loading order, because it has to be correct to work.. Or does it for dynamic libraries?
- // Anyways it's required for static libraries (especially on Windows)
+ // Anyways it's required for static libraries
for (const string &binaryDependency : binaryDependencies)
{
allLinkerFlags += " ";
@@ -413,6 +439,7 @@ namespace backend
}
string staticLinkerFlags;
+ auto parentProjStaticLinkerFlagCallbackFunc = staticLinkerFlagCallbackFunc;
if (!staticLinkerFlagCallbackFunc || libraryType == LibraryType::DYNAMIC)
{
staticLinkerFlagCallbackFunc = [&staticLinkerFlags](const string &linkerFlag)
@@ -423,8 +450,8 @@ namespace backend
}
string dynamicLinkerFlags;
- // TODO: Do same for cmake
- if (!sourceFiles.empty())
+ auto parentProjDynamicLinkerFlagCallbackFunc = dynamicLinkerFlagCallback;
+ if(!dynamicLinkerFlagCallback || libraryType != LibraryType::STATIC)
{
dynamicLinkerFlagCallback = [&dynamicLinkerFlags](const string &linkerFlag)
{
@@ -439,6 +466,10 @@ namespace backend
cflags += " ";
cflags += dependencyCflags;
};
+
+ Result<bool> buildSubProjectResult = buildSubProjects(staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
+ if(!buildSubProjectResult)
+ return buildSubProjectResult;
Result<bool> linkerFlags = getLinkerFlags(config, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback, cflagsCallbackFunc);
if (linkerFlags.isErr())
@@ -739,13 +770,13 @@ namespace backend
objectNames.emplace_back(objectName);
}
- string projectGeneratedBinary;
+ string projectGeneratedBinaryFlags;
if (!sourceFiles.empty())
{
- projectGeneratedBinary = allLinkerFlags;
- projectGeneratedBinary += " \"";
+ string projectGeneratedBinary = "\"";
projectGeneratedBinary += savePathUtf8;
projectGeneratedBinary += "/";
+
switch (libraryType)
{
case LibraryType::EXECUTABLE:
@@ -776,7 +807,11 @@ namespace backend
result += allLinkerFlags;
}
result += "\n\n";
+
projectGeneratedBinary += config.getPackageName();
+ #if OS_FAMILY == OS_FAMILY_WINDOWS
+ projectGeneratedBinary += ".exe";
+ #endif
break;
}
case LibraryType::STATIC:
@@ -804,6 +839,11 @@ namespace backend
break;
}
}
+
+ projectGeneratedBinary += "\"";
+ if(parentProjStaticLinkerFlagCallbackFunc)
+ parentProjStaticLinkerFlagCallbackFunc(projectGeneratedBinary);
+
break;
}
case LibraryType::DYNAMIC:
@@ -841,13 +881,19 @@ namespace backend
//result += " '-Wl,--no-whole-archive'";
}
result += "\n\n";
+
+ projectGeneratedBinary += "\"";
+ if(parentProjDynamicLinkerFlagCallbackFunc)
+ parentProjDynamicLinkerFlagCallbackFunc(projectGeneratedBinary);
+
break;
}
default:
assert(false);
return Result<bool>::Err("Unexpected error");
}
- projectGeneratedBinary += "\"";
+
+ projectGeneratedBinaryFlags = allLinkerFlags + " " + projectGeneratedBinary;
Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size()));
if (fileOverwriteResult.isErr())
@@ -863,30 +909,14 @@ namespace backend
// TODO: If tests are being run (sibs test) and root project is an executable, do not run compile (above code) as executable.
// Sibs test will compile root project as dynamic library so you end up compiling the project twice, first as an executable and then as a dynamic library.
// Even if the root project has been built before and there is cached object, it will take a few seconds to run compile
- Result<bool> buildTestResult = buildTests(projectGeneratedBinary, config, savePath, dependencyExportIncludeDirs);
+ Result<bool> buildTestResult = buildTests(projectGeneratedBinaryFlags, config, savePath, dependencyExportIncludeDirs);
if(!buildTestResult)
return buildTestResult;
return Result<bool>::Ok(true);
}
- // TODO: Add "c++" file extension, seems to be used in some places?
- const _tinydir_char_t *sourceFileExtensions[] = { TINYDIR_STRING("c"), TINYDIR_STRING("cc"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx") };
- bool isSourceFile(tinydir_file *file)
- {
- if(!file->is_reg)
- return false;
-
- for(const _tinydir_char_t *sourceFileExtension : sourceFileExtensions)
- {
- if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
- return true;
- }
-
- return false;
- }
-
- Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary, const SibsConfig &config, const _tinydir_char_t *savePath, const string &parentDependencyExportIncludeDirs)
+ Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinaryFlags, const SibsConfig &config, const _tinydir_char_t *savePath, const string &parentDependencyExportIncludeDirs)
{
if(testSourceDirs.empty() || !config.shouldBuildTests())
return Result<bool>::Ok(true);
@@ -940,12 +970,12 @@ namespace backend
backend::Ninja ninja;
ninja.addGlobalIncludeDirs(parentExportIncludeDirs);
- if(!projectGeneratedBinary.empty())
- ninja.addDependency(projectGeneratedBinary);
+ if(!projectGeneratedBinaryFlags.empty())
+ ninja.addDependency(projectGeneratedBinaryFlags);
// TODO: Use same source file finder as in main.cpp
walkDirFilesRecursive(testSourceDirNative.c_str(), [&ninja, &sibsTestConfig](tinydir_file *file)
{
- if (isSourceFile(file))
+ if (backend::BackendUtils::isSourceFile(file))
{
string filePathUtf8 = toUtf8(file->path + sibsTestConfig.getProjectPath().size() + 1);
ninja.addSourceFile(filePathUtf8.c_str());
diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp
index 8411137..7bbff51 100644
--- a/backend/ninja/Ninja.hpp
+++ b/backend/ninja/Ninja.hpp
@@ -11,6 +11,24 @@
namespace backend
{
+ class Ninja;
+
+ struct NinjaSubProject
+ {
+ Ninja *subProject;
+ sibs::SibsConfig *config;
+ sibs::FileString buildPath;
+
+ NinjaSubProject() : subProject(nullptr), config(nullptr) {}
+ NinjaSubProject(Ninja *_subProject, sibs::SibsConfig *_config, sibs::FileString &&_buildPath) :
+ subProject(_subProject),
+ config(_config),
+ buildPath(move(_buildPath))
+ {
+
+ }
+ };
+
class Ninja
{
public:
@@ -27,10 +45,12 @@ namespace backend
void addSourceFile(const char *filepath);
void addTestSourceDir(const char *dir);
void addDependency(const std::string &binaryFile);
+ void addSubProject(Ninja *subProject, sibs::SibsConfig *config, sibs::FileString &&buildPath);
const std::vector<std::string>& getSourceFiles() const;
sibs::Result<bool> build(const sibs::SibsConfig &config, const _tinydir_char_t *savePath, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc = nullptr, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback = nullptr, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback = nullptr);
private:
- sibs::Result<bool> buildTests(const std::string &projectGeneratedBinary, const sibs::SibsConfig &config, const _tinydir_char_t *savePath, const std::string &parentDependencyExportIncludeDirs);
+ sibs::Result<bool> buildSubProjects(sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback);
+ sibs::Result<bool> buildTests(const std::string &projectGeneratedBinaryFlags, const sibs::SibsConfig &config, const _tinydir_char_t *savePath, const std::string &parentDependencyExportIncludeDirs);
bool containsSourceFile(const std::string &filepath) const;
bool containsTestSourceDir(const std::string &dir) const;
bool containsDependency(const std::string &dependency) const;
@@ -41,6 +61,7 @@ namespace backend
std::vector<std::string> sourceFiles;
std::vector<std::string> testSourceDirs;
std::vector<std::string> binaryDependencies;
+ std::vector<NinjaSubProject> subProjects;
};
}
diff --git a/include/Conf.hpp b/include/Conf.hpp
index 13245c1..6a6d07c 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -99,7 +99,7 @@ namespace sibs
class Config
{
public:
- static Result<bool> readFromFile(const _tinydir_char_t *filepath, const ConfigCallback &callback);
+ static Result<bool> readFromFile(const _tinydir_char_t *filepath, ConfigCallback &callback);
};
enum OptimizationLevel
@@ -449,6 +449,8 @@ namespace sibs
void processField(StringView name, const ConfigValue &value) override;
void finished() override;
};
+
+ void readSibsConfig(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig, FileString &buildPath);
}
#endif //SIBS_CONF_HPP
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp
index 990bf36..eeb8a9c 100644
--- a/src/CmakeModule.cpp
+++ b/src/CmakeModule.cpp
@@ -53,12 +53,15 @@ namespace sibs
}
string dynamicLinkerFlags;
- // TODO: If project contains no source files, then we shouldn't override this function
- dynamicLinkerFlagCallbackFunc = [&dynamicLinkerFlags](const string &linkerFlag)
+ // TODO: If project contains no source files, then we shouldn't override this function... why?
+ if(!dynamicLinkerFlagCallbackFunc || config.getPackageType() != PackageType::STATIC)
{
- dynamicLinkerFlags += " ";
- dynamicLinkerFlags += linkerFlag;
- };
+ dynamicLinkerFlagCallbackFunc = [&dynamicLinkerFlags](const string &linkerFlag)
+ {
+ dynamicLinkerFlags += " ";
+ dynamicLinkerFlags += linkerFlag;
+ };
+ }
// TODO: Create a cmake module that contains library/include path for the dependencies (https://cmake.org/Wiki/CMake:How_To_Find_Libraries).
// Modify the project CMakeLists.txt and add: list(APPEND CMAKE_MODULE_PATH "PathToDependenciesCmakeModulesGoesHere").
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 41cc157..941bdd7 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -1,10 +1,17 @@
#include "../include/Conf.hpp"
#include "../include/types.hpp"
#include "../external/utf8/unchecked.h"
+#include <iostream>
using namespace std;
using u8string = utf8::unchecked::iterator<char*>;
+#if OS_FAMILY == OS_FAMILY_POSIX
+#define ferr std::cerr
+#else
+#define ferr std::wcerr
+#endif
+
namespace sibs
{
static const string EMPTY_STRING = "";
@@ -196,11 +203,11 @@ namespace sibs
class Parser
{
public:
- static Result<bool> parse(const char *code, const ConfigCallback &callback)
+ static Result<bool> parse(const char *code, ConfigCallback &callback)
{
try
{
- Parser parser(code, (ConfigCallback*)&callback);
+ Parser parser(code, &callback);
parser.parse();
return Result<bool>::Ok(true);
}
@@ -438,7 +445,7 @@ namespace sibs
bool objectDefined;
};
- Result<bool> Config::readFromFile(const _tinydir_char_t *filepath, const ConfigCallback &callback)
+ Result<bool> Config::readFromFile(const _tinydir_char_t *filepath, ConfigCallback &callback)
{
Result<StringView> fileContentResult = getFileContent(filepath);
if(fileContentResult.isErr())
@@ -463,6 +470,50 @@ namespace sibs
}
return false;
}
+
+ void readSibsConfig(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig, FileString &buildPath)
+ {
+ Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
+ if(result.isErr())
+ {
+ ferr << "Failed to read config: " << toFileString(result.getErrMsg()) << endl;
+ exit(6);
+ }
+
+ if(sibsConfig.getPackageName().empty())
+ {
+ ferr << "project.conf is missing required field package.name" << endl;
+ exit(10);
+ }
+
+ if (!containsPlatform(sibsConfig.getPlatforms(), SYSTEM_PLATFORM))
+ {
+ string errMsg = "The project ";
+ errMsg += sibsConfig.getPackageName();
+ errMsg += " does not support your platform (";
+ errMsg += asString(SYSTEM_PLATFORM);
+ errMsg += ")";
+ cerr << errMsg << endl;
+ exit(11);
+ }
+
+ buildPath = projectPath + TINYDIR_STRING("/sibs-build/");
+ switch(sibsConfig.getOptimizationLevel())
+ {
+ case OPT_LEV_DEBUG:
+ buildPath += TINYDIR_STRING("debug");
+ break;
+ case OPT_LEV_RELEASE:
+ buildPath += TINYDIR_STRING("release");
+ break;
+ }
+
+ if(sibsConfig.shouldBuildTests() && sibsConfig.getTestPath().empty())
+ {
+ printf("Project is missing package.tests config. No tests to build\n");
+ exit(0);
+ }
+ }
const char* asString(Platform platform)
{
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index eee37dd..8618cfd 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -1,5 +1,6 @@
#include "../include/GlobalLib.hpp"
#include "../include/FileUtil.hpp"
+#include "../backend/BackendUtils.hpp"
#include "../backend/ninja/Ninja.hpp"
#include "../include/Conf.hpp"
#include "../include/curl.hpp"
@@ -46,26 +47,6 @@ namespace sibs
}
}
}
-
- const _tinydir_char_t *sourceFileExtensions[] = { TINYDIR_STRING("c"),TINYDIR_STRING("cc"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx") };
- bool isSourceFile(tinydir_file *file)
- {
- if(!file->is_reg)
- return false;
-
- for(const _tinydir_char_t *sourceFileExtension : sourceFileExtensions)
- {
- if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
- return true;
- }
-
- return false;
- }
-
- bool isPathSubPathOf(const _tinydir_char_t *path, const FileString &subPathOf)
- {
- return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0;
- }
Result<bool> GlobalLib::getLibs(const std::vector<PackageListDependency*> &libs, const SibsConfig &parentConfig, const FileString &globalLibRootDir, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
@@ -284,93 +265,7 @@ namespace sibs
else
{
backend::Ninja ninja;
- // TODO: Use same source file finder as in main.cpp
- FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file)
- {
- FileString pathNative = file->path;
- #if OS_FAMILY == OS_FAMILY_WINDOWS
- replaceChar(pathNative, L'/', L'\\');
- #endif
- if(file->is_reg)
- {
- if (isSourceFile(file))
- {
- string fileNameNative = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size() + 1);
- ninja.addSourceFile(fileNameNative.c_str());
- }
- else
- {
- //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
- }
- }
- else
- {
- // TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests...
- // OR I believe there is no reason to run tests in dependencies. The main projects tests should cover that?
- // But you might want to know exactly which dependency is causing issue and which part of it...
- if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath()))
- {
- string filePathUtf8 = toUtf8(pathNative.c_str());
- ninja.addTestSourceDir(filePathUtf8.c_str());
- }
- else if(!directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs()))
- walkDir(file->path, collectSourceFiles);
- }
- };
- walkDir(packageDir.c_str(), collectSourceFiles);
-
- if (!ninja.getSourceFiles().empty())
- {
- string libPath = toUtf8(buildPath);
- switch (sibsConfig.getCompiler())
- {
- case Compiler::GCC:
- {
- libPath += "/lib";
- libPath += dependencyName;
- if (sibsConfig.getPackageType() == PackageType::STATIC)
- {
- libPath += ".a";
- string libPathCmd = "'";
- libPathCmd += libPath;
- libPathCmd += "'";
- staticLinkerFlagCallbackFunc(libPathCmd);
- }
- else
- {
- libPath += ".so";
- string libPathCmd = "'";
- libPathCmd += libPath;
- libPathCmd += "'";
- dynamicLinkerFlagCallbackFunc(libPathCmd);
- }
- break;
- }
- case Compiler::MSVC:
- {
- libPath += "/";
- libPath += dependencyName;
- if (sibsConfig.getPackageType() == PackageType::STATIC)
- {
- libPath += ".lib";
- string libPathCmd = "\"";
- libPathCmd += libPath;
- libPathCmd += "\"";
- staticLinkerFlagCallbackFunc(libPathCmd);
- }
- else
- {
- libPath += ".lib";
- string libPathCmd = "\"";
- libPathCmd += libPath;
- libPathCmd += "\"";
- dynamicLinkerFlagCallbackFunc(libPathCmd);
- }
- break;
- }
- }
- }
-
+ backend::BackendUtils::collectSourceFiles(packageDir.c_str(), &ninja, sibsConfig);
return ninja.build(sibsConfig, buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback);
}
}
diff --git a/src/main.cpp b/src/main.cpp
index b9d6c1b..910380a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -6,6 +6,7 @@
#include "../include/Conf.hpp"
#include "../include/Exec.hpp"
#include "../include/CmakeModule.hpp"
+#include "../backend/BackendUtils.hpp"
#include "../backend/ninja/Ninja.hpp"
using namespace std;
@@ -42,11 +43,6 @@ using namespace std::chrono;
// Might need to make it possible to define variables if a dependency exists (or doesn't exist) because the code might have
// preprocessor like: USE_LIBSODIUM or NO_LIBSODIUM.
-// TODO: Set c++ standard to c++11 and c standard to c98 - for consistency across different compilers and compiler version.
-// It should be possible to override language version in project.conf
-
-// TODO: If file extension is common c extension (.c, ...) then remove cast checking (for example using malloc without casting result to result type)
-
// TODO: When building a sibs project, add a hardlink in ~/.sibs/lib to it. This allows us to have dependency to a project that we can modify
// without having to commit & push to remote
@@ -199,48 +195,17 @@ bool isPathSubPathOf(const FileString &path, const FileString &subPathOf)
return _tinydir_strncmp(path.c_str(), subPathOf.c_str(), subPathOf.size()) == 0;
}
-int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, const SibsConfig &sibsConfig)
+int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig)
{
- Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
- if(result.isErr())
- {
- ferr << "Failed to read config: " << toFileString(result.getErrMsg()) << endl;
- exit(6);
- }
-
- if(sibsConfig.getPackageName().empty())
- {
- ferr << "project.conf is missing required field package.name" << endl;
- exit(10);
- }
-
- if (!containsPlatform(sibsConfig.getPlatforms(), SYSTEM_PLATFORM))
- {
- string errMsg = "The project ";
- errMsg += sibsConfig.getPackageName();
- errMsg += " does not support your platform (";
- errMsg += asString(SYSTEM_PLATFORM);
- errMsg += ")";
- cerr << errMsg << endl;
- exit(11);
- }
-
- FileString buildPath = projectPath + TINYDIR_STRING("/sibs-build/");
- switch(sibsConfig.getOptimizationLevel())
- {
- case OPT_LEV_DEBUG:
- buildPath += TINYDIR_STRING("debug");
- break;
- case OPT_LEV_RELEASE:
- buildPath += TINYDIR_STRING("release");
- break;
- }
+ FileString buildPath;
+ readSibsConfig(projectPath, projectConfFilePath, sibsConfig, buildPath);
auto startTime = high_resolution_clock::now();
if(sibsConfig.shouldUseCmake())
{
auto dummyCallback = [](const string&){};
+ // TODO: Add test and sub projects
CmakeModule cmakeModule;
Result<bool> cmakeCompileResult = cmakeModule.compile(sibsConfig, buildPath, dummyCallback, dummyCallback, dummyCallback);
if(!cmakeCompileResult)
@@ -252,42 +217,36 @@ int buildProject(const FileString &projectPath, const FileString &projectConfFil
else
{
backend::Ninja ninja;
- FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file)
+ // TODO: Do same for cmake
+ switch (sibsConfig.getOptimizationLevel())
{
- FileString pathNative = file->path;
- #if OS_FAMILY == OS_FAMILY_WINDOWS
- replaceChar(pathNative, L'/', L'\\');
- #endif
- if(file->is_reg)
+ case OPT_LEV_DEBUG:
{
- if (isSourceFile(file))
+ // TODO: Check if this dependency is static or dynamic and decide which lib path to use from that
+ for(const string &staticLib : sibsConfig.getDebugStaticLibs())
{
- string filePathUtf8 = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size());
- ninja.addSourceFile(filePathUtf8.c_str());
- }
- else
- {
- //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
+ string staticLibCmd = "\"";
+ staticLibCmd += staticLib;
+ staticLibCmd += "\"";
+ ninja.addDependency(staticLibCmd);
}
+ break;
}
- else
+ case OPT_LEV_RELEASE:
{
- if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath()))
+ // TODO: Check if this dependency is static or dynamic and decide which lib path to use from that
+ for (const string &staticLib : sibsConfig.getReleaseStaticLibs())
{
- string filePathUtf8 = toUtf8(pathNative.c_str());
- ninja.addTestSourceDir(filePathUtf8.c_str());
+ string staticLibCmd = "\"";
+ staticLibCmd += staticLib;
+ staticLibCmd += "\"";
+ ninja.addDependency(staticLibCmd);
}
- else if(!directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs()))
- walkDir(file->path, collectSourceFiles);
+ break;
}
- };
- walkDir(projectPath.c_str(), collectSourceFiles);
-
- if(sibsConfig.shouldBuildTests() && sibsConfig.getTestPath().empty())
- {
- printf("Project is missing package.tests config. No tests to build\n");
- exit(0);
}
+
+ backend::BackendUtils::collectSourceFiles(projectPath.c_str(), &ninja, sibsConfig);
Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str());
if(buildFileResult.isErr())