aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-31 05:24:40 +0100
committerdec05eba <dec05eba@protonmail.com>2017-12-31 05:26:07 +0100
commit017ec45e94204f977dcd7b04c8035d48f230ded3 (patch)
tree7778ecc069f05fb527329f36876ed13a17a48ab3
parent7a5910121ab0ad2ea8a4a60e5b6599b7255e5a5e (diff)
Sibs can now build itself on windows
Fixed several bugs. The windows implementation IS QUICK AND DIRTY! It links things as static even if you wish to link as dynamic etc..... NEED TO FIX THIS !!!
-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"