aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--backend/ninja/Ninja.cpp375
-rw-r--r--backend/ninja/Ninja.hpp8
-rw-r--r--include/Conf.hpp66
-rw-r--r--include/FileUtil.hpp1
-rw-r--r--include/GlobalLib.hpp2
-rw-r--r--include/Linker.hpp1
-rw-r--r--include/env.hpp10
-rw-r--r--project.conf7
-rw-r--r--src/Conf.cpp226
-rw-r--r--src/FileUtil.cpp14
-rw-r--r--src/GlobalLib.cpp97
-rw-r--r--src/main.cpp21
-rw-r--r--tests/project.conf2
-rw-r--r--tests/src/confTest/confTest.cpp6
-rw-r--r--tests/src/main.cpp2
16 files changed, 604 insertions, 235 deletions
diff --git a/.gitignore b/.gitignore
index 2a323e3..29a2471 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ sibs-build
.idea/
.kdev4/
sibs.kdev4
+build
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 49bda4f..0b46891 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -90,6 +90,33 @@ namespace backend
return result;
}
+ string getDefineFlag(Compiler compiler, const string &name, const string &value)
+ {
+ string result;
+ switch (compiler)
+ {
+ case Compiler::GCC:
+ {
+ result = "'-D";
+ result += name;
+ result += "=";
+ result += value;
+ result += "'";
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ result = "\"/D";
+ result += name;
+ result += "=";
+ result += value;
+ result += "\"";
+ break;
+ }
+ }
+ return result;
+ }
+
string getCompileWithoutLinkingFlag(Compiler compiler)
{
string result;
@@ -221,7 +248,7 @@ namespace backend
#endif
// 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 SibsConfig &config, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const
+ Result<bool> Ninja::getLinkerFlags(const SibsConfig &config, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) const
{
const vector<Dependency> &dependencies = config.getDependencies();
if(dependencies.empty()) return Result<bool>::Ok(true);
@@ -277,7 +304,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(config, globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
+ Result<bool> globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(config, globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
if(globalLibLinkerFlagsResult.isErr())
{
if(globalLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_NOT_FOUND || globalLibLinkerFlagsResult.getErrorCode() == GlobalLib::DependencyError::DEPENDENCY_VERSION_NO_MATCH)
@@ -296,7 +323,7 @@ namespace backend
if(downloadDependencyResult.isErr())
return downloadDependencyResult;
- globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(config, globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
+ globalLibLinkerFlagsResult = GlobalLib::getLibsLinkerFlags(config, globalLibDir, globalLibDependency.name, globalLibDependency.version, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
if(globalLibLinkerFlagsResult.isErr())
return Result<bool>::Err(globalLibLinkerFlagsResult);
}
@@ -310,19 +337,19 @@ namespace backend
return Result<bool>::Ok(true);
}
- Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback)
+ Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
- // TODO: Do not quit here if no source files are provided. The source-less project could have dependencies
- if(sourceFiles.empty())
- return Result<bool>::Err("No source files provided");
-
- Result<bool> createBuildDirResult = createDirectoryRecursive(savePath);
- if(createBuildDirResult.isErr())
- return createBuildDirResult;
+ if (!sourceFiles.empty())
+ {
+ Result<bool> createBuildDirResult = createDirectoryRecursive(savePath);
+ if (createBuildDirResult.isErr())
+ return createBuildDirResult;
+ }
LibraryType libraryType = getNinjaLibraryType(config.getPackageType());
string savePathUtf8 = toUtf8(savePath);
+ string projectPathUtf8 = toUtf8(config.getProjectPath());
FileString ninjaBuildFilePath = savePath;
ninjaBuildFilePath += TINYDIR_STRING("/build.ninja");
@@ -336,9 +363,11 @@ namespace backend
FileString globalIncDir = globalIncDirResult.unwrap();
globalIncDir += TINYDIR_STRING("/.sibs/lib");
+ string globalIncDirUtf8 = toUtf8(globalIncDir);
result += "globalIncDir = ";
- result += getIncludeOptionFlag(config.getCompiler(), toUtf8(globalIncDir));
+ result += getIncludeOptionFlag(config.getCompiler(), globalIncDirUtf8);
+
for(const auto &includeDir : config.getIncludeDirs())
{
string includeDirRelative = "../../";
@@ -346,16 +375,67 @@ namespace backend
result += " ";
result += getIncludeOptionFlag(config.getCompiler(), includeDirRelative);
}
+
+ auto parentGlobalIncludeDirCallback = globalIncludeDirCallback;
+ for (const string &globalIncludeDir : config.getGlobalIncludeDirs())
+ {
+ string globalIncludeDirFull = projectPathUtf8;
+ globalIncludeDirFull += "/";
+ globalIncludeDirFull += globalIncludeDir;
+ if(parentGlobalIncludeDirCallback)
+ parentGlobalIncludeDirCallback(globalIncludeDirFull);
+ }
+
+ globalIncludeDirCallback = [&parentGlobalIncludeDirCallback, &globalIncludeDirCallback, &result, &config](const string &globalIncludeDir)
+ {
+ result += " ";
+ result += getIncludeOptionFlag(config.getCompiler(), globalIncludeDir);
+ if (parentGlobalIncludeDirCallback)
+ parentGlobalIncludeDirCallback(globalIncludeDir);
+ };
+
+#if OS_TYPE == OS_TYPE_LINUX
+ // TODO: Allow configuring default linking flags. Maybe have `package.useThreads = false` to disable this flag
+ string allLinkerFlags = "-pthread";
+#else
+ string allLinkerFlags = "";
+#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)
+ for (const string &binaryDependency : binaryDependencies)
+ {
+ allLinkerFlags += " ";
+ allLinkerFlags += binaryDependency;
+ }
+
+ if (!staticLinkerFlagCallbackFunc || libraryType == LibraryType::DYNAMIC)
+ {
+ staticLinkerFlagCallbackFunc = [&allLinkerFlags](const string &linkerFlag)
+ {
+ allLinkerFlags += " ";
+ allLinkerFlags += linkerFlag;
+ };
+ }
+
+ // TODO: If project contains no source files, then we shouldn't override this function
+ dynamicLinkerFlagCallback = [&allLinkerFlags](const string &linkerFlag)
+ {
+ allLinkerFlags += " ";
+ allLinkerFlags += linkerFlag;
+ };
+
+ Result<bool> linkerFlags = getLinkerFlags(config, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
+ if (linkerFlags.isErr())
+ return Result<bool>::Err(linkerFlags.getErrMsg());
+
result += "\n\n";
string defines;
for(const auto &definePair : config.getDefines())
{
- defines += " '-D";
- defines += definePair.first;
- defines += "=";
- defines += definePair.second;
- defines += "'";
+ defines += " ";
+ defines += getDefineFlag(config.getCompiler(), definePair.first, definePair.second);
}
if(!defines.empty())
@@ -452,6 +532,7 @@ namespace backend
return Result<bool>::Err("Unexpected error");
}
+ // TODO: Add equivalent functionality for msvc. Currently msvc always builds as debug build
string optimizationFlags;
switch(config.getOptimizationLevel())
{
@@ -482,156 +563,156 @@ namespace backend
result += " ARGS = $globalIncDir ";
if(!defines.empty())
result += defines;
- if(config.getCompiler() != Compiler::MSVC)
- result += " '-I" + config.getPackageName() + "@exe' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' " + optimizationFlags + " '-g'";
+ switch (config.getCompiler())
+ {
+ case Compiler::GCC:
+ {
+ result += " '-I" + config.getPackageName() + "@exe' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' " + optimizationFlags + " '-g'";
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ result += " /EHsc";
+ switch (config.getOptimizationLevel())
+ {
+ case OPT_LEV_DEBUG:
+ result += " /MTd";
+ break;
+ case OPT_LEV_RELEASE:
+ result += " /MT";
+ break;
+ }
+ switch (SYSTEM_PLATFORM)
+ {
+ case PLATFORM_WIN32:
+ result += " /MACHINE:X86";
+ break;
+ case PLATFORM_WIN64:
+ result += " /MACHINE:X64";
+ break;
+ }
+ break;
+ }
+ }
result += "\n\n";
objectNames.emplace_back(objectName);
}
-#if OS_TYPE == OS_TYPE_LINUX
- // TODO: Allow configuring default linking flags. Maybe have `package.useThreads = false` to disable this flag
- string allLinkerFlags = "-pthread";
-#else
- string allLinkerFlags = "";
-#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)
- for(const string &binaryDependency : binaryDependencies)
+ string projectGeneratedBinary;
+ if (!sourceFiles.empty())
{
- allLinkerFlags += " ";
- allLinkerFlags += binaryDependency;
- }
-
- if(!staticLinkerFlagCallbackFunc || libraryType == LibraryType::DYNAMIC)
- {
- staticLinkerFlagCallbackFunc = [&allLinkerFlags](const string &linkerFlag)
+ projectGeneratedBinary = allLinkerFlags;
+ projectGeneratedBinary += " \"";
+ projectGeneratedBinary += savePathUtf8;
+ projectGeneratedBinary += "/";
+ switch (libraryType)
{
- allLinkerFlags += " ";
- allLinkerFlags += linkerFlag;
- };
- }
-
- // TODO: If project contains no source files, then we shouldn't override this function
- dynamicLinkerFlagCallback = [&allLinkerFlags](const string &linkerFlag)
- {
- allLinkerFlags += " ";
- allLinkerFlags += linkerFlag;
- };
-
- Result<bool> linkerFlags = getLinkerFlags(config, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback);
- if(linkerFlags.isErr())
- return Result<bool>::Err(linkerFlags.getErrMsg());
-
- string projectGeneratedBinary = allLinkerFlags;
- projectGeneratedBinary += " '";
- projectGeneratedBinary += savePathUtf8;
- projectGeneratedBinary += "/";
- switch(libraryType)
- {
- case LibraryType::EXECUTABLE:
- {
- result += "build ";
- result += config.getPackageName();
- result += ": " + buildJob + " ";
- result += join(objectNames, " ");
- result += "\n";
- switch (config.getCompiler())
+ case LibraryType::EXECUTABLE:
{
- case Compiler::GCC:
+ result += "build ";
+ result += config.getPackageName();
+ result += ": " + buildJob + " ";
+ result += join(objectNames, " ");
+ result += "\n";
+ switch (config.getCompiler())
{
- result += " LINK_ARGS = '-Wl,--no-undefined,--as-needed' ";
- break;
+ case Compiler::GCC:
+ {
+ result += " LINK_ARGS = '-Wl,--no-undefined,--as-needed' ";
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ // TODO: Do not link all of these. Find a way to only link the ones that are needed
+ result += " LINK_ARGS = Ws2_32.lib Wldap32.lib Crypt32.lib Advapi32.lib Gdi32.lib User32.lib ";
+ break;
+ }
}
- case Compiler::MSVC:
+
+ if (!allLinkerFlags.empty())
{
- result += " LINK_ARGS = ";
- break;
+ result += allLinkerFlags;
}
+ result += "\n\n";
+ projectGeneratedBinary += config.getPackageName();
+ break;
}
-
- if(!allLinkerFlags.empty())
+ case LibraryType::STATIC:
{
- result += allLinkerFlags;
- }
- result += "\n\n";
- projectGeneratedBinary += config.getPackageName();
- break;
- }
- case LibraryType::STATIC:
- {
- result += "build ";
- result += config.getPackageName();
- result += ": " + buildJob + " ";
- result += join(objectNames, " ");
- result += "\n\n";
+ result += "build ";
+ result += config.getPackageName();
+ result += ": " + buildJob + " ";
+ result += join(objectNames, " ");
+ result += "\n\n";
- switch (config.getCompiler())
- {
- case Compiler::GCC:
+ switch (config.getCompiler())
{
- projectGeneratedBinary += config.getPackageName() + ".a";
- break;
- }
- case Compiler::MSVC:
- {
- projectGeneratedBinary += config.getPackageName() + ".lib";
- break;
+ case Compiler::GCC:
+ {
+ projectGeneratedBinary += config.getPackageName() + ".a";
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ projectGeneratedBinary += config.getPackageName() + ".lib";
+ break;
+ }
}
+ break;
}
- break;
- }
- case LibraryType::DYNAMIC:
- {
- switch (config.getCompiler())
+ case LibraryType::DYNAMIC:
{
- case Compiler::GCC:
+ switch (config.getCompiler())
{
- result += "build lib";
- result += config.getPackageName();
- result += ".so: " + buildJob + " ";
- result += join(objectNames, " ");
- result += "\n";
- result += " LINK_ARGS = '-Wl,--no-undefined,--as-needed' ";
- projectGeneratedBinary += "lib" + config.getPackageName() + ".so";
- break;
+ case Compiler::GCC:
+ {
+ result += "build lib";
+ result += config.getPackageName();
+ result += ".so: " + buildJob + " ";
+ result += join(objectNames, " ");
+ result += "\n";
+ result += " LINK_ARGS = '-Wl,--no-undefined,--as-needed' ";
+ projectGeneratedBinary += "lib" + config.getPackageName() + ".so";
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ result += "build ";
+ result += config.getPackageName();
+ result += ".lib: " + buildJob + " ";
+ result += join(objectNames, " ");
+ result += "\n";
+ // TODO: Do not link all of these. Find a way to only link the ones that are needed
+ result += " LINK_ARGS = Ws2_32.lib Wldap32.lib Crypt32.lib Advapi32.lib Gdi32.lib User32.lib ";
+ projectGeneratedBinary += config.getPackageName() + ".lib";
+ break;
+ }
}
- case Compiler::MSVC:
+
+ if (!allLinkerFlags.empty())
{
- result += "build ";
- result += config.getPackageName();
- result += ".lib: " + buildJob + " ";
- result += join(objectNames, " ");
- result += "\n";
- result += " LINK_ARGS = ";
- projectGeneratedBinary += config.getPackageName() + ".lib";
- break;
+ result += allLinkerFlags;
+ //result += " '-Wl,--no-whole-archive'";
}
+ result += "\n\n";
+ break;
}
-
- if(!allLinkerFlags.empty())
- {
- result += allLinkerFlags;
- //result += " '-Wl,--no-whole-archive'";
- }
- result += "\n\n";
- break;
+ default:
+ assert(false);
+ return Result<bool>::Err("Unexpected error");
}
- default:
- assert(false);
- return Result<bool>::Err("Unexpected error");
- }
- projectGeneratedBinary += "'";
+ projectGeneratedBinary += "\"";
- Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size()));
- if(fileOverwriteResult.isErr())
- return fileOverwriteResult;
+ Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size()));
+ if (fileOverwriteResult.isErr())
+ return fileOverwriteResult;
- nprintf(TINYDIR_STRING("Created ninja build file: %s\n"), ninjaBuildFilePath.c_str());
+ nprintf(TINYDIR_STRING("Created ninja build file: %s\n"), ninjaBuildFilePath.c_str());
- Result<bool> buildResult = build(savePath);
- if(!buildResult)
- return buildResult;
+ Result<bool> buildResult = compile(savePath);
+ if (!buildResult)
+ return buildResult;
+ }
Result<bool> buildTestResult = buildTests(projectGeneratedBinary, config, savePath);
if(!buildTestResult)
@@ -655,8 +736,10 @@ namespace backend
return false;
}
- Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary, const SibsConfig &config, const char *savePath)
+ Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary, const SibsConfig &config, const _tinydir_char_t *savePath)
{
+ printf("build tests!\n");
+
if(testSourceDirs.empty())
return Result<bool>::Ok(true);
@@ -671,6 +754,7 @@ namespace backend
// TODO: Do not allow defining `main` in project.conf or as program argument to sibs (when sibs supports defines).
// It's ok if `define` fails. It could fail if `main` has already been replaced by other tests somehow.
parentProjConfigLib.define("main", "sibs_lib_ignore_main");
+ parentProjConfigLib.define("wmain", "sibs_lib_ignore_wmain");
return build(parentProjConfigLib, savePath, nullptr, nullptr);
}
@@ -686,7 +770,7 @@ namespace backend
projectConfFilePath += TINYDIR_STRING("/project.conf");
FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
- SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative);
+ SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative, config.getOptimizationLevel());
if(projectConfFileType == FileType::REGULAR)
{
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig);
@@ -695,7 +779,8 @@ namespace backend
}
backend::Ninja ninja;
- ninja.addDependency(projectGeneratedBinary);
+ if(!projectGeneratedBinary.empty())
+ ninja.addDependency(projectGeneratedBinary);
walkDirFilesRecursive(testSourceDirNative.c_str(), [&ninja, &sibsTestConfig](tinydir_file *file)
{
if (isSourceFile(file))
@@ -716,7 +801,7 @@ namespace backend
if (!buildFileResult)
return buildFileResult;
- Result<bool> buildResult = ninja.build(debugBuildPath.c_str());
+ Result<bool> buildResult = ninja.compile(debugBuildPath.c_str());
if (!buildResult)
return buildResult;
}
@@ -725,7 +810,7 @@ namespace backend
return Result<bool>::Ok(true);
}
- Result<bool> Ninja::build(const _tinydir_char_t *buildFilePath)
+ Result<bool> Ninja::compile(const _tinydir_char_t *buildFilePath)
{
FileString command = TINYDIR_STRING("ninja -C \"");
command += buildFilePath;
diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp
index 36a57ff..eeea1be 100644
--- a/backend/ninja/Ninja.hpp
+++ b/backend/ninja/Ninja.hpp
@@ -28,14 +28,14 @@ namespace backend
void addTestSourceDir(const char *dir);
void addDependency(const std::string &binaryFile);
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::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 char *savePath);
+ sibs::Result<bool> buildTests(const std::string &projectGeneratedBinary, const sibs::SibsConfig &config, const _tinydir_char_t *savePath);
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 sibs::SibsConfig &config, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback) const;
- sibs::Result<bool> build(const _tinydir_char_t *buildFilePath);
+ sibs::Result<bool> getLinkerFlags(const sibs::SibsConfig &config, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback) const;
+ sibs::Result<bool> compile(const _tinydir_char_t *buildFilePath);
private:
std::vector<std::string> sourceFiles;
std::vector<std::string> testSourceDirs;
diff --git a/include/Conf.hpp b/include/Conf.hpp
index d147fca..2cb387c 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -99,6 +99,46 @@ namespace sibs
MSVC
};
+ enum Platform
+ {
+ PLATFORM_ANY,
+
+ PLATFORM_LINUX32,
+ PLATFORM_LINUX64,
+
+ PLATFORM_WIN32,
+ PLATFORM_WIN64
+ };
+
+ // TODO: Detect this at runtime?
+ #if OS_TYPE == OS_TYPE_WINDOWS
+ #ifdef SIBS_ENV_32BIT
+ const Platform SYSTEM_PLATFORM = Platform::PLATFORM_WIN32;
+ const StringView CONFIG_SYSTEM_PLATFORM = "config.win32";
+ const StringView CONFIG_STATIC_DEBUG_PLATFORM = "config.win32.static.debug";
+ const StringView CONFIG_STATIC_RELEASE_PLATFORM = "config.win32.static.release";
+ #else
+ const Platform SYSTEM_PLATFORM = Platform::PLATFORM_WIN64;
+ const StringView CONFIG_SYSTEM_PLATFORM = "config.win64";
+ const StringView CONFIG_STATIC_DEBUG_PLATFORM = "config.win64.static.debug";
+ const StringView CONFIG_STATIC_RELEASE_PLATFORM = "config.win64.static.release";
+ #endif
+ #elif OS_TYPE == OS_TYPE_LINUX
+ #ifdef SIBS_ENV_32BIT
+ const Platform SYSTEM_PLATFORM = Platform::PLATFORM_LINUX32;
+ const StringView CONFIG_SYSTEM_PLATFORM = "config.linux32";
+ const StringView CONFIG_STATIC_DEBUG_PLATFORM = "config.linux32.static.debug";
+ const StringView CONFIG_STATIC_RELEASE_PLATFORM = "config.linux32.static.release";
+ #else
+ const Platform SYSTEM_PLATFORM = Platform::PLATFORM_LINUX64;
+ const StringView CONFIG_SYSTEM_PLATFORM = "config.linux64";
+ const StringView CONFIG_STATIC_DEBUG_PLATFORM = "config.linux64.static.debug";
+ const StringView CONFIG_STATIC_RELEASE_PLATFORM = "config.linux64.static.release";
+ #endif
+ #endif
+
+ bool containsPlatform(const std::vector<Platform> &platforms, Platform platform);
+ const char* asString(Platform platform);
const char* asString(OptimizationLevel optLevel);
class SibsConfig : public ConfigCallback
@@ -144,10 +184,30 @@ namespace sibs
return includeDirs;
}
+ virtual const std::vector<std::string>& getGlobalIncludeDirs() const
+ {
+ return exposeIncludeDirs;
+ }
+
+ virtual const std::vector<Platform>& getPlatforms() const
+ {
+ return platforms;
+ }
+
virtual OptimizationLevel getOptimizationLevel() const
{
return optimizationLevel;
}
+
+ const std::vector<std::string>& getDebugStaticLibs() const
+ {
+ return debugStaticLibs;
+ }
+
+ const std::vector<std::string>& getReleaseStaticLibs() const
+ {
+ return releaseStaticLibs;
+ }
void setPackageType(PackageType packageType)
{
@@ -170,15 +230,19 @@ namespace sibs
PackageType packageType;
std::vector<Dependency> dependencies;
std::vector<std::string> includeDirs;
+ std::vector<std::string> exposeIncludeDirs;
+ std::vector<Platform> platforms;
std::unordered_map<std::string, std::string> defines;
OptimizationLevel optimizationLevel;
+ std::vector<std::string> debugStaticLibs;
+ std::vector<std::string> releaseStaticLibs;
bool finishedProcessing;
};
class SibsTestConfig : public SibsConfig
{
public:
- SibsTestConfig(Compiler _compiler, const FileString &_projectPath) : SibsConfig(_compiler, _projectPath)
+ SibsTestConfig(Compiler _compiler, const FileString &_projectPath, OptimizationLevel _optimizationLevel) : SibsConfig(_compiler, _projectPath, _optimizationLevel)
{
packageName = "test";
}
diff --git a/include/FileUtil.hpp b/include/FileUtil.hpp
index 89eaa84..f2679a0 100644
--- a/include/FileUtil.hpp
+++ b/include/FileUtil.hpp
@@ -30,6 +30,7 @@ namespace sibs
FileString utf8To16(const std::string &utf8Str);
FileString toFileString(const std::string &utf8Str);
FileString getLastErrorAsString();
+ void replaceChar(FileString &input, wchar_t charToReplace, wchar_t charToReplaceWith);
#endif
using FileWalkCallbackFunc = std::function<void(tinydir_file*)>;
diff --git a/include/GlobalLib.hpp b/include/GlobalLib.hpp
index 2f4b938..b098543 100644
--- a/include/GlobalLib.hpp
+++ b/include/GlobalLib.hpp
@@ -18,7 +18,7 @@ namespace sibs
};
static Result<bool> validatePackageExists(const FileString &globalLibRootDir, const std::string &name);
- static Result<std::string> getLibsLinkerFlags(const SibsConfig &parentConfig, const FileString &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc);
+ static Result<bool> getLibsLinkerFlags(const SibsConfig &parentConfig, const FileString &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback);
static Result<bool> downloadDependency(const Dependency &dependency);
};
}
diff --git a/include/Linker.hpp b/include/Linker.hpp
index 7ea7b48..90bebe2 100644
--- a/include/Linker.hpp
+++ b/include/Linker.hpp
@@ -6,6 +6,7 @@
namespace sibs
{
using LinkerFlagCallbackFunc = std::function<void(const std::string&)>;
+ using GlobalIncludeDirCallbackFunc = std::function<void(const std::string&)>;
}
#endif //SIBS_LINKER_HPP
diff --git a/include/env.hpp b/include/env.hpp
index 51ee2bd..1ea55ca 100644
--- a/include/env.hpp
+++ b/include/env.hpp
@@ -9,9 +9,9 @@
#if defined(_WIN32) || defined(_WIN64)
#if defined(_WIN64)
- #define CISB_ENV_64BIT
+ #define SIBS_ENV_64BIT
#else
- #define CISB_ENV_32BIT
+ #define SIBS_ENV_32BIT
#endif
#define OS_FAMILY OS_FAMILY_WINDOWS
#define OS_TYPE OS_TYPE_WINDOWS
@@ -41,13 +41,13 @@
#if defined(__GNUC__)
#if defined(__x86_64__) || defined(__pc64__)
- #define CISB_ENV_64BIT
+ #define SIBS_ENV_64BIT
#else
- #define CISB_ENV_32BIT
+ #define SIBS_ENV_32BIT
#endif
#endif
-#if !defined(CISB_ENV_32BIT) && !defined(CISB_ENV_64BIT)
+#if !defined(SIBS_ENV_32BIT) && !defined(SIBS_ENV_64BIT)
#error "System is not detected as either 32-bit or 64-bit"
#endif
diff --git a/project.conf b/project.conf
index 3f46ea9..0bbac1f 100644
--- a/project.conf
+++ b/project.conf
@@ -1,10 +1,11 @@
[package]
name = "sibs"
type = "executable"
-version = "0.1.0"
+version = "0.1.1"
authors = ["DEC05EBA <0xdec05eba@gmail.com>"]
tests = "tests"
+platforms = ["linux32", "linux64", "win64"]
[dependencies]
-libcurl = "7"
-libarchive = "3.3"
+libcurl = "7.57.0"
+libarchive = "3.3.2"
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 5282bb5..4217846 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -24,7 +24,8 @@ namespace sibs
OPEN_BRACKET,
CLOSING_BRACKET,
EQUALS,
- STRING
+ STRING,
+ COMMA
};
const char *getTokenName(Token token)
@@ -38,6 +39,7 @@ namespace sibs
case Token::CLOSING_BRACKET: return "]";
case Token::EQUALS: return "=";
case Token::STRING: return "string";
+ case Token::COMMA: return ",";
default: return "Unknown";
}
}
@@ -61,12 +63,12 @@ namespace sibs
c = *code;
}
- if(isAlpha(c) || c == '_')
+ if(isIdentifierChar(c))
{
char *startOfIdentifier = code.base();
++code;
c = *code;
- while(isAlpha(c) || isDigit(c) || c == '_' || c == '-')
+ while(isIdentifierChar(c))
{
++code;
c = *code;
@@ -115,6 +117,11 @@ namespace sibs
++code;
return Token::STRING;
}
+ else if (c == ',')
+ {
+ ++code;
+ return Token::COMMA;
+ }
else if(c == '\0')
{
return Token::END_OF_FILE;
@@ -144,6 +151,11 @@ namespace sibs
{
return c >= '0' && c <= '9';
}
+
+ bool isIdentifierChar(u32 c)
+ {
+ return isAlpha(c) || isDigit(c) || c == '_' || c == '-' || c == '.';
+ }
private:
Token currentToken;
u8string code;
@@ -238,7 +250,7 @@ namespace sibs
}
}
- void parseConfigFieldRhs(StringView fieldName)
+ void parseConfigFieldRhs(const StringView &fieldName)
{
Token token = tokenizer.nextToken();
if(token == Token::STRING)
@@ -247,39 +259,48 @@ namespace sibs
}
else if(token == Token::OPEN_BRACKET)
{
+ parseConfigFieldRhsList(fieldName);
+ }
+ else
+ {
+ string errMsg = "Expected string on right-hand side of field '";
+ errMsg += string(fieldName.data, fieldName.size);
+ errMsg += "', got: ";
+ errMsg += getTokenName(token);
+ throw ParserException(errMsg);
+ }
+ }
+
+ void parseConfigFieldRhsList(const StringView &fieldName)
+ {
+ Token token = tokenizer.nextToken();
+ if (token == Token::CLOSING_BRACKET) return;
+
+ vector<StringView> values;
+ while (true)
+ {
+ if (token == Token::STRING)
+ values.push_back(tokenizer.getString());
+
token = tokenizer.nextToken();
- if(token == Token::STRING)
+ if (token == Token::COMMA)
{
- StringView str = tokenizer.getString();
token = tokenizer.nextToken();
- if(token == Token::CLOSING_BRACKET)
- {
- vector<StringView> values;
- values.push_back(str);
- callback->processField(fieldName, values);
- }
- else
- {
- string errMsg = "Expected ']' to close value list, got: ";
- errMsg += getTokenName(token);
- throw ParserException(errMsg);
- }
+ continue;
+ }
+ else if (token == Token::CLOSING_BRACKET)
+ {
+ break;
}
else
{
- string errMsg = "Expected string value inside list in field definition, got: ";
+ string errMsg = "Expected list value to be followed by ']' or ',', got: ";
errMsg += getTokenName(token);
throw ParserException(errMsg);
}
}
- else
- {
- string errMsg = "Expected string on right-hand side of field '";
- errMsg += string(fieldName.data, fieldName.size);
- errMsg += "', got: ";
- errMsg += getTokenName(token);
- throw ParserException(errMsg);
- }
+
+ callback->processField(fieldName, values);
}
void parseConfigObject()
@@ -330,6 +351,28 @@ namespace sibs
return Parser::parse(code, callback);
}
+ bool containsPlatform(const vector<Platform> &platforms, Platform platform)
+ {
+ for (Platform vecPlatform : platforms)
+ {
+ if (vecPlatform == platform || vecPlatform == PLATFORM_ANY)
+ return true;
+ }
+ return false;
+ }
+
+ const char* asString(Platform platform)
+ {
+ switch (platform)
+ {
+ case PLATFORM_ANY: return "any";
+ case PLATFORM_LINUX32: return "linux32";
+ case PLATFORM_LINUX64: return "linux64";
+ case PLATFORM_WIN32: return "win32";
+ case PLATFORM_WIN64: return "win64";
+ }
+ }
+
const char* asString(OptimizationLevel optLevel)
{
switch(optLevel)
@@ -361,6 +404,33 @@ namespace sibs
return defines;
}
+ void getLibFiles(const string &libPath, vector<string> &outputFiles)
+ {
+ FileString nativePath = toFileString(libPath);
+ FileType fileType = getFileType(nativePath.c_str());
+ switch (fileType)
+ {
+ case FileType::FILE_NOT_FOUND:
+ {
+ string errMsg = "Path not found: ";
+ errMsg += libPath;
+ throw ParserException(errMsg);
+ }
+ case FileType::REGULAR:
+ {
+ string errMsg = "Expected path ";
+ errMsg += libPath;
+ errMsg += " to be a directory, was a regular file";
+ throw ParserException(errMsg);
+ }
+ }
+
+ walkDirFiles(nativePath.c_str(), [&outputFiles](tinydir_file *file)
+ {
+ outputFiles.push_back(toUtf8(file->path));
+ });
+ }
+
void SibsConfig::processObject(StringView name)
{
currentObject = name;
@@ -462,6 +532,108 @@ namespace sibs
else
throw ParserException("Expected package.include_dirs to be a list, was a single value");
}
+ else if (name.equals("platforms"))
+ {
+ if (value.isList())
+ {
+ // TODO: Checking for duplicate declaration should be done in the config parser
+ if (!platforms.empty())
+ throw ParserException("Found duplicate declaration of package.platforms");
+
+ for (const StringView &platform : value.asList())
+ {
+ if (platform.equals("any"))
+ {
+ platforms.push_back(PLATFORM_ANY);
+ }
+ else if (platform.equals("linux32"))
+ {
+ platforms.push_back(PLATFORM_LINUX32);
+ }
+ else if (platform.equals("linux64"))
+ {
+ platforms.push_back(PLATFORM_LINUX64);
+ }
+ else if (platform.equals("win32"))
+ {
+ platforms.push_back(PLATFORM_WIN32);
+ }
+ else if (platform.equals("win64"))
+ {
+ platforms.push_back(PLATFORM_WIN64);
+ }
+ else
+ {
+ string errMsg = "package.platforms contains invalid platform \"";
+ errMsg += string(platform.data, platform.size);
+ errMsg += "\". Expected platform to be one of: any, linux32, linux64, win32 or win64";
+ throw ParserException(errMsg);
+ }
+ }
+ }
+ else
+ throw ParserException("Expected package.platforms to be a list, was a single value");
+ }
+ }
+ else if (currentObject.equals(CONFIG_SYSTEM_PLATFORM))
+ {
+ if (name.equals("expose_include_dirs"))
+ {
+ if (value.isList())
+ {
+ for (const StringView &includeDir : value.asList())
+ {
+ exposeIncludeDirs.emplace_back(string(includeDir.data, includeDir.size));
+ }
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += " to be a list, was a single value";
+ throw ParserException(errMsg);
+ }
+ }
+ }
+ else if (currentObject.equals(CONFIG_STATIC_DEBUG_PLATFORM))
+ {
+ if (name.equals("lib"))
+ {
+ if (value.isSingle())
+ {
+ string debugStaticLibPath = toUtf8(projectPath);
+ debugStaticLibPath += "/";
+ debugStaticLibPath += string(value.asSingle().data, value.asSingle().size);
+ getLibFiles(debugStaticLibPath, debugStaticLibs);
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += " to be a single value, was a list";
+ throw ParserException(errMsg);
+ }
+ }
+ }
+ else if (currentObject.equals(CONFIG_STATIC_RELEASE_PLATFORM))
+ {
+ if (name.equals("lib"))
+ {
+ if (value.isSingle())
+ {
+ string releaseStaticLibPath = toUtf8(projectPath);
+ releaseStaticLibPath += "/";
+ releaseStaticLibPath += string(value.asSingle().data, value.asSingle().size);
+ getLibFiles(releaseStaticLibPath, releaseStaticLibs);
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += " to be a single value, was a list";
+ throw ParserException(errMsg);
+ }
+ }
}
else if(currentObject.equals("dependencies"))
{
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp
index 5cf8377..db68bb4 100644
--- a/src/FileUtil.cpp
+++ b/src/FileUtil.cpp
@@ -68,6 +68,16 @@ namespace sibs
LocalFree(messageBuffer);
return message;
}
+
+ void replaceChar(FileString &input, wchar_t charToReplace, wchar_t charToReplaceWith)
+ {
+ for (int i = 0; i < input.size(); ++i)
+ {
+ wchar_t c = input[i];
+ if (c == charToReplace)
+ input[i] = charToReplaceWith;
+ }
+ }
#endif
#if OS_FAMILY == OS_FAMILY_POSIX
@@ -100,7 +110,7 @@ namespace sibs
{
tinydir_file file;
tinydir_readfile(&dir, &file);
- if(_tinydir_strcmp(file.name, TINYDIR_STRING(".")) != 0 && _tinydir_strcmp(file.name, TINYDIR_STRING("..")) != 0)
+ if(_tinydir_strncmp(file.name, TINYDIR_STRING("."), 1) != 0)
callbackFunc(&file);
tinydir_next(&dir);
}
@@ -138,7 +148,7 @@ namespace sibs
tinydir_readfile(&dir, &file);
if(file.is_reg)
callbackFunc(&file);
- else if(_tinydir_strcmp(file.name, TINYDIR_STRING(".")) != 0 && _tinydir_strcmp(file.name, TINYDIR_STRING("..")) != 0)
+ else if(_tinydir_strncmp(file.name, TINYDIR_STRING("."), 1) != 0)
walkDirFilesRecursive(file.path, callbackFunc);
tinydir_next(&dir);
}
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index fde7797..ac8fd59 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -64,11 +64,11 @@ namespace sibs
return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0;
}
- Result<string> GlobalLib::getLibsLinkerFlags(const SibsConfig &parentConfig, const FileString &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc)
+ Result<bool> GlobalLib::getLibsLinkerFlags(const SibsConfig &parentConfig, const FileString &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
Result<bool> packageExistsResult = validatePackageExists(globalLibRootDir, name);
- if(packageExistsResult.isErr())
- return Result<string>::Err(packageExistsResult);
+ if (packageExistsResult.isErr())
+ return packageExistsResult;
#if OS_FAMILY == OS_FAMILY_POSIX
FileString namePlatformNative = name;
@@ -95,7 +95,7 @@ namespace sibs
});
if(foundVersion.empty())
- return Result<string>::Err("Global lib dependency found, but version doesn't match dependency version", DependencyError::DEPENDENCY_VERSION_NO_MATCH);
+ return Result<bool>::Err("Global lib dependency found, but version doesn't match dependency version", DependencyError::DEPENDENCY_VERSION_NO_MATCH);
packageDir += TINYDIR_STRING("/");
packageDir += versionPlatformNative;
@@ -111,41 +111,55 @@ namespace sibs
string errMsg = "Global lib dependency found: ";
errMsg += toUtf8(packageDir);
errMsg += ", but it's missing a project.conf file";
- return Result<string>::Err(errMsg);
+ return Result<bool>::Err(errMsg);
}
case FileType::DIRECTORY:
{
string errMsg = "Global lib dependency found: ";
errMsg += toUtf8(packageDir);
errMsg += ", but it's corrupt (Found directory instead of file)";
- return Result<string>::Err(errMsg);
+ return Result<bool>::Err(errMsg);
}
}
SibsConfig sibsConfig(parentConfig.getCompiler(), packageDir, parentConfig.getOptimizationLevel());
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
- if(result.isErr())
- return Result<string>::Err(result.getErrMsg());
+ if (result.isErr())
+ return result;
if(sibsConfig.getPackageName().empty())
- return Result<string>::Err("project.conf is missing required field package.name");
+ return Result<bool>::Err("project.conf is missing required field package.name");
if(sibsConfig.getPackageType() == PackageType::EXECUTABLE)
{
string errMsg = "The dependency ";
errMsg += name;
errMsg += " is an executable. Only libraries can be dependencies";
- return Result<string>::Err(errMsg);
+ return Result<bool>::Err(errMsg);
+ }
+
+ if (!containsPlatform(sibsConfig.getPlatforms(), SYSTEM_PLATFORM))
+ {
+ string errMsg = "The dependency ";
+ errMsg += name;
+ errMsg += " does not support your platform (";
+ errMsg += asString(SYSTEM_PLATFORM);
+ errMsg += ")";
+ return Result<bool>::Err(errMsg);
}
backend::Ninja ninja;
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(file->path + sibsConfig.getProjectPath().size() + 1);
+ string fileNameNative = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size() + 1);
ninja.addSourceFile(fileNameNative.c_str());
}
else
@@ -158,9 +172,9 @@ namespace sibs
// 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(file->path, sibsConfig.getTestPath()))
+ if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath()))
{
- string filePathUtf8 = toUtf8(file->path);
+ string filePathUtf8 = toUtf8(pathNative.c_str());
ninja.addTestSourceDir(filePathUtf8.c_str());
}
else
@@ -169,24 +183,39 @@ namespace sibs
};
walkDir(packageDir.c_str(), collectSourceFiles);
- // TODO: Dont do this. Unit tests wont be built. Need to call the below ninja.createBuildFile
- if(ninja.getSourceFiles().empty())
- {
- return Result<string>::Ok("No source files in dependency (header only library?)");
- }
- else
+ FileString buildPath = packageDir + TINYDIR_STRING("/sibs-build/");
+ switch (sibsConfig.getOptimizationLevel())
{
- FileString buildPath = packageDir + TINYDIR_STRING("/sibs-build/");
- switch(sibsConfig.getOptimizationLevel())
+ case OPT_LEV_DEBUG:
{
- case OPT_LEV_DEBUG:
- buildPath += TINYDIR_STRING("debug");
- break;
- case OPT_LEV_RELEASE:
- buildPath += TINYDIR_STRING("release");
- break;
+ buildPath += TINYDIR_STRING("debug");
+ // 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 staticLibCmd = "\"";
+ staticLibCmd += staticLib;
+ staticLibCmd += "\"";
+ staticLinkerFlagCallbackFunc(staticLibCmd);
+ }
+ break;
+ }
+ case OPT_LEV_RELEASE:
+ {
+ buildPath += TINYDIR_STRING("release");
+ // 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 staticLibCmd = "\"";
+ staticLibCmd += staticLib;
+ staticLibCmd += "\"";
+ staticLinkerFlagCallbackFunc(staticLibCmd);
+ }
+ break;
}
+ }
+ if (!ninja.getSourceFiles().empty())
+ {
string libPath = toUtf8(buildPath);
switch (sibsConfig.getCompiler())
{
@@ -235,19 +264,9 @@ namespace sibs
break;
}
}
-
- // 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(buildPath.c_str());
- if(createBuildDirResult.isErr())
- return Result<string>::Err(createBuildDirResult);
-
- Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc);
- if (buildFileResult.isErr())
- return Result<string>::Err(buildFileResult.getErrMsg());
-
- return Result<string>::Ok(libPath);
}
+
+ return ninja.build(sibsConfig, buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback);
}
Result<bool> GlobalLib::downloadDependency(const Dependency &dependency)
diff --git a/src/main.cpp b/src/main.cpp
index 855b1dc..1c2492c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -208,17 +208,32 @@ int buildProject(int argc, const _tinydir_char_t **argv)
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);
+ }
+
//string projectSrcPath = projectPath + "/src";
//validateDirectoryPath(projectSrcPath.c_str());
backend::Ninja ninja;
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 filePathUtf8 = toUtf8(file->path + sibsConfig.getProjectPath().size());
+ string filePathUtf8 = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size());
ninja.addSourceFile(filePathUtf8.c_str());
}
else
@@ -229,9 +244,9 @@ int buildProject(int argc, const _tinydir_char_t **argv)
else
{
// TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests
- if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
+ if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath()))
{
- string filePathUtf8 = toUtf8(file->path);
+ string filePathUtf8 = toUtf8(pathNative.c_str());
ninja.addTestSourceDir(filePathUtf8.c_str());
}
else
diff --git a/tests/project.conf b/tests/project.conf
index 6a33314..0f33088 100644
--- a/tests/project.conf
+++ b/tests/project.conf
@@ -1,2 +1,2 @@
[dependencies]
-catch2 = "0.1.0"
+catch2 = "2.0.1" \ No newline at end of file
diff --git a/tests/src/confTest/confTest.cpp b/tests/src/confTest/confTest.cpp
index eaf5c0b..e1b5b7a 100644
--- a/tests/src/confTest/confTest.cpp
+++ b/tests/src/confTest/confTest.cpp
@@ -1,12 +1,12 @@
-#include "catch2/0.1.0/catch.hpp"
+#include "catch2/2.0.1/catch.hpp"
#include "../../../include/Conf.hpp"
using namespace sibs;
TEST_CASE("parse config")
{
- SibsConfig sibsConfig(Compiler::GCC, "tests/src/confTest");
- Result<bool> result = Config::readFromFile("tests/src/confTest/project.conf", sibsConfig);
+ SibsConfig sibsConfig(Compiler::GCC, TINYDIR_STRING("tests/src/confTest"));
+ Result<bool> result = Config::readFromFile(TINYDIR_STRING("tests/src/confTest/project.conf"), sibsConfig);
if(result.isErr())
{
fprintf(stderr, "%s", result.getErrMsg().c_str());
diff --git a/tests/src/main.cpp b/tests/src/main.cpp
index d29d915..50ecd8b 100644
--- a/tests/src/main.cpp
+++ b/tests/src/main.cpp
@@ -1,2 +1,2 @@
#define CATCH_CONFIG_MAIN
-#include "catch2/0.1.0/catch.hpp"
+#include "catch2/2.0.1/catch.hpp"