aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md24
-rw-r--r--include/Conf.hpp79
-rw-r--r--include/FileUtil.hpp2
-rw-r--r--src/Conf.cpp64
-rw-r--r--src/FileUtil.cpp12
-rwxr-xr-xtest.sh7
-rw-r--r--tests/src/confTest/confTest.cpp11
-rw-r--r--tests/src/confTest/validProject.conf12
8 files changed, 210 insertions, 1 deletions
diff --git a/README.md b/README.md
index 7f43ccd..f328152 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,17 @@ lib = "windows/x86/static/release"
[config.win64.static.debug]
lib = "windows/x64/static/debug"
+
+# cmake building is currrently not implemented, but it is intended to work like this
+[cmake]
+dir = "."
+args = ["ENTITYX_RUN_BENCHMARKS=0"]
+
+[cmake.static]
+args = ["ENTITYX_BUILD_SHARED=0"]
+
+[cmake.dynamic]
+args = ["ENTITYX_BUILD_SHARED=1"]
```
## package
### name
@@ -75,3 +86,16 @@ Optional. The name is structured in the following way: config.platform.libraryTy
where platform is any of the platforms specified under \[package] (or if package contains "any", then it can be any other platform). LibraryType is either "static" or "dynamic" - different configurations depending on if the package is included as a static or dynamic library by a dependant package. OptimizationLevel is either "debug" or "release", depending on which optimization level the "root" package was built with ("root" package is usually the project which is an executable)
### lib
Optional. A directory which contains .lib or .dll files which should be included in dependant projects that uses this project
+## cmake
+Optional. Using this allows you to build cmake projects. If a project contains cmake in the project.conf file, then sibs wont build the project itself
+and will use cmake instead. Sibs will put the built executable and library files into the same location they would be if sibs build them,
+meaning you can have dependency to a cmake project from a sibs project and it will automatically use the dependency library files
+### dir
+Optional. Directory that contains CMakeLists.txt. If this is not specified, the project root will be used (same location where project.conf is located)
+### args
+Optional. List of arguments to cmake. The arguments should be in the same format as "-D" arguments (options) in cmake, except they should exclude "-D".
+Do not use CMAKE_BUILD_TYPE as sibs will automatically use it depending on the optimization level the user specifies when building project.
+## cmake.*
+Optional. The name is structured in the following way: config.libraryType
+where libraryType is either "static" or "dynamic" - different configurations depending on if the package is included as a static or dynamic library by a dependant package.
+Args specified under \[cmake.static] or \[cmake.dynamic] are appended to the args specified under \[cmake]
diff --git a/include/Conf.hpp b/include/Conf.hpp
index 75076fa..d3d80f9 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -146,7 +146,28 @@ namespace sibs
class SibsConfig : public ConfigCallback
{
public:
- SibsConfig(Compiler _compiler, const FileString &_projectPath, OptimizationLevel _optimizationLevel = OPT_LEV_DEBUG) : compiler(_compiler), projectPath(_projectPath), packageType((PackageType)-1), optimizationLevel(_optimizationLevel), finishedProcessing(false) {}
+ SibsConfig(Compiler _compiler, const FileString &_projectPath, OptimizationLevel _optimizationLevel = OPT_LEV_DEBUG) :
+ compiler(_compiler),
+ projectPath(_projectPath),
+ packageType((PackageType)-1),
+ optimizationLevel(_optimizationLevel),
+ finishedProcessing(false),
+ useCmake(false)
+ {
+ cmakeDirGlobal = projectPath;
+ cmakeDirStatic = cmakeDirGlobal;
+ cmakeDirDynamic = cmakeDirGlobal;
+ switch(optimizationLevel)
+ {
+ case OPT_LEV_DEBUG:
+ cmakeArgsGlobal = "\"-DCMAKE_BUILD_TYPE=Debug\"";
+ break;
+ case OPT_LEV_RELEASE:
+ cmakeArgsGlobal = "\"-DCMAKE_BUILD_TYPE=Release\"";
+ break;
+ }
+ }
+
virtual ~SibsConfig(){}
Compiler getCompiler() const
@@ -216,6 +237,54 @@ namespace sibs
return ignoreDirs;
}
+ const FileString& getCmakeDir() const
+ {
+ return cmakeDirGlobal;
+ }
+
+ const FileString& getCmakeDirStatic() const
+ {
+ return cmakeDirStatic;
+ }
+
+ const FileString& getCmakeDirDynamic() const
+ {
+ return cmakeDirDynamic;
+ }
+
+ // Get cmake args for all builds. This is args under [cmake] only
+ const std::string& getCmakeArgs() const
+ {
+ return cmakeArgsGlobal;
+ }
+
+ // Get cmake args for static build. This is a combination of args under [cmake] and under [cmake.static]
+ std::string getCmakeArgsStatic() const
+ {
+ std::string result;
+ result.reserve(cmakeArgsGlobal.size() + 1 + cmakeArgsStatic.size());
+ result += cmakeArgsGlobal;
+ result += " ";
+ result += cmakeArgsStatic;
+ return result;
+ }
+
+ // Get cmake args for dynamic build. This is a combination of args under [cmake] and under [cmake.dynamic]
+ std::string getCmakeArgsDynamic() const
+ {
+ std::string result;
+ result.reserve(cmakeArgsGlobal.size() + 1 + cmakeArgsDynamic.size());
+ result += cmakeArgsGlobal;
+ result += " ";
+ result += cmakeArgsDynamic;
+ return result;
+ }
+
+ bool shouldUseCmake() const
+ {
+ return useCmake;
+ }
+
void setPackageType(PackageType packageType)
{
this->packageType = packageType;
@@ -230,6 +299,7 @@ namespace sibs
virtual void finished() override;
void failInvalidFieldUnderObject(const StringView &fieldName) const;
private:
+ void parseCmake(const StringView &fieldName, const ConfigValue &fieldValue, std::string &cmakeDir, std::string &cmakeArgs);
void validatePackageName() const;
protected:
StringView currentObject;
@@ -247,6 +317,13 @@ namespace sibs
OptimizationLevel optimizationLevel;
std::vector<std::string> debugStaticLibs;
std::vector<std::string> releaseStaticLibs;
+ FileString cmakeDirGlobal;
+ FileString cmakeDirStatic;
+ FileString cmakeDirDynamic;
+ std::string cmakeArgsGlobal;
+ std::string cmakeArgsStatic;
+ std::string cmakeArgsDynamic;
+ bool useCmake;
bool finishedProcessing;
};
diff --git a/include/FileUtil.hpp b/include/FileUtil.hpp
index 90b9ca3..64d0c99 100644
--- a/include/FileUtil.hpp
+++ b/include/FileUtil.hpp
@@ -23,12 +23,14 @@ namespace sibs
#if OS_FAMILY == OS_FAMILY_POSIX
#define toUtf8(input) input
FileString toFileString(const std::string &utf8Str);
+ FileString toFileString(const StringView &utf8Str);
#else
std::string toUtf8(const sibs::FileString &input);
std::string toUtf8(const TCHAR *input);
FileString utf8To16(const StringView &utf8Str);
FileString utf8To16(const std::string &utf8Str);
FileString toFileString(const std::string &utf8Str);
+ FileString toFileString(const StringView &utf8Str);
FileString getLastErrorAsString();
void replaceChar(FileString &input, wchar_t charToReplace, wchar_t charToReplaceWith);
#endif
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 27713d8..39a8c1d 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -456,6 +456,8 @@ namespace sibs
void SibsConfig::processObject(StringView name)
{
currentObject = name;
+ if(currentObject.equals("cmake") || currentObject.equals("cmake.static") || currentObject.equals("cmake.dynamic"))
+ useCmake = true;
//printf("Process object: %.*s\n", name.size, name.data);
}
@@ -730,6 +732,18 @@ namespace sibs
else
throw ParserException("Expected field under dependencies to be a single value, was a list");
}
+ else if(currentObject.equals("cmake"))
+ {
+ parseCmake(name, value, cmakeDirGlobal, cmakeArgsGlobal);
+ }
+ else if(currentObject.equals("cmake.static"))
+ {
+ parseCmake(name, value, cmakeDirStatic, cmakeArgsStatic);
+ }
+ else if(currentObject.equals("cmake.dynamic"))
+ {
+ parseCmake(name, value, cmakeDirDynamic, cmakeArgsDynamic);
+ }
else
{
string errMsg = "Invalid config object \"";
@@ -738,6 +752,56 @@ namespace sibs
throw ParserException(errMsg);
}
}
+
+ void SibsConfig::parseCmake(const StringView &fieldName, const ConfigValue &fieldValue, string &cmakeDir, string &cmakeArgs)
+ {
+ if(fieldName.equals("dir"))
+ {
+ if(fieldValue.isSingle())
+ {
+ cmakeDir = projectPath;
+ cmakeDir += TINYDIR_STRING("/");
+ cmakeDir += toFileString(fieldValue.asSingle());
+ // No need to validate if CMakeLists.txt exists here, cmake will tell us if the file doesn't exist
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg.append(currentObject.data, currentObject.size);
+ errMsg += ".";
+ errMsg.append(fieldName.data, fieldName.size);
+ errMsg += " to be a single value, was a list";
+ throw ParserException(errMsg);
+ }
+ }
+ else if(fieldName.equals("args"))
+ {
+ if(fieldValue.isList())
+ {
+ for(const StringView &arg : fieldValue.asList())
+ {
+ bool prependSpace = !cmakeArgs.empty();
+ cmakeArgs.reserve(cmakeArgs.size() + 4 + (prependSpace ? 1 : 0) + arg.size);
+ if(prependSpace)
+ cmakeArgs += " ";
+ cmakeArgs += "\"-D";
+ cmakeArgs.append(arg.data, arg.size);
+ cmakeArgs += "\"";
+ }
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg.append(currentObject.data, currentObject.size);
+ errMsg += ".";
+ errMsg.append(fieldName.data, fieldName.size);
+ errMsg += " to be a list, was a single value";
+ throw ParserException(errMsg);
+ }
+ }
+ else
+ failInvalidFieldUnderObject(fieldName);
+ }
void SibsConfig::finished()
{
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp
index e53aa85..2626ee3 100644
--- a/src/FileUtil.cpp
+++ b/src/FileUtil.cpp
@@ -23,6 +23,11 @@ namespace sibs
{
return utf8Str;
}
+
+ FileString toFileString(const StringView &utf8Str)
+ {
+ return FileString(utf8Str.data, utf8Str.size);
+ }
#else
std::string toUtf8(const sibs::FileString &input)
{
@@ -57,6 +62,13 @@ namespace sibs
{
return utf8To16(utf8Str);
}
+
+ FileString toFileString(const StringView &utf8Str)
+ {
+ FileString result;
+ utf8::utf8to16(utf8Str.data, utf8Str.data + utf8Str.size, std::back_inserter(result));
+ return result;
+ }
FileString getLastErrorAsString()
{
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..6806e13
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+set -e
+
+sibs build
+./sibs-build/debug/sibs build
+./tests/sibs-build/debug/test
diff --git a/tests/src/confTest/confTest.cpp b/tests/src/confTest/confTest.cpp
index 17b5995..e508e84 100644
--- a/tests/src/confTest/confTest.cpp
+++ b/tests/src/confTest/confTest.cpp
@@ -27,6 +27,17 @@ TEST_CASE("parse config")
const auto &catch2Dependency = sibsConfig.getDependencies()[1];
REQUIRE(catch2Dependency.name == "catch2");
REQUIRE(catch2Dependency.version == "1.0.0");
+
+ REQUIRE(sibsConfig.shouldUseCmake());
+
+ REQUIRE(sibsConfig.getCmakeDir() == TINYDIR_STRING("tests/src/confTest/cmakeGlobal"));
+ REQUIRE(sibsConfig.getCmakeArgs() == "\"-DCMAKE_BUILD_TYPE=Debug\" \"-DENTITYX_RUN_BENCHMARKS=0\"");
+
+ REQUIRE(sibsConfig.getCmakeDirStatic() == TINYDIR_STRING("tests/src/confTest/cmakeStatic"));
+ REQUIRE(sibsConfig.getCmakeArgsStatic() == "\"-DCMAKE_BUILD_TYPE=Debug\" \"-DENTITYX_RUN_BENCHMARKS=0\" \"-DENTITYX_BUILD_TESTING=0\"");
+
+ REQUIRE(sibsConfig.getCmakeDirDynamic() == TINYDIR_STRING("tests/src/confTest/cmakeDynamic"));
+ REQUIRE(sibsConfig.getCmakeArgsDynamic() == "\"-DCMAKE_BUILD_TYPE=Debug\" \"-DENTITYX_RUN_BENCHMARKS=0\" \"-DENTITYX_BUILD_TESTING=0\" \"-DENTITYX_BUILD_SHARED=1\"");
}
TEST_CASE("parse config - invalid object")
diff --git a/tests/src/confTest/validProject.conf b/tests/src/confTest/validProject.conf
index de5112d..eab258b 100644
--- a/tests/src/confTest/validProject.conf
+++ b/tests/src/confTest/validProject.conf
@@ -7,3 +7,15 @@ platforms = ["linux64", "win64"]
[dependencies]
xxhash = "0.1.0"
catch2 = "1.0.0"
+
+[cmake]
+dir = "cmakeGlobal"
+args = ["ENTITYX_RUN_BENCHMARKS=0"]
+
+[cmake.static]
+dir = "cmakeStatic"
+args = ["ENTITYX_BUILD_TESTING=0"]
+
+[cmake.dynamic]
+dir = "cmakeDynamic"
+args = ["ENTITYX_BUILD_TESTING=0", "ENTITYX_BUILD_SHARED=1"]