aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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())