aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-01-06 09:38:59 +0100
committerdec05eba <dec05eba@protonmail.com>2018-01-06 09:41:18 +0100
commitad3b5099263e5977d1de9bfcff715a92009e8355 (patch)
treefd49aca56de6253efc4c2720423a65142bc4c150
parentea17671d7fe9ece8a33bdbc2f1d7bdf68bbccb69 (diff)
Add define.static, define.dynamic
-rw-r--r--include/Conf.hpp5
-rw-r--r--src/Conf.cpp63
-rw-r--r--src/main.cpp2
-rw-r--r--tests/src/confTest/confTest.cpp30
-rw-r--r--tests/src/confTest/defineDynamic.conf17
-rw-r--r--tests/src/confTest/defineStatic.conf17
6 files changed, 134 insertions, 0 deletions
diff --git a/include/Conf.hpp b/include/Conf.hpp
index c661ca4..950b25a 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -331,11 +331,16 @@ namespace sibs
virtual bool isDefined(const std::string &name) const;
virtual bool define(const std::string &name, const std::string &value);
virtual const std::unordered_map<std::string, std::string>& getDefines() const;
+
+ // Get define value by name.
+ // Return empty string if the value is empty or if the defined value doesn't exist
+ const std::string& getDefinedValue(const std::string &name) const;
protected:
virtual void processObject(StringView name) override;
virtual void processField(StringView name, const ConfigValue &value) override;
virtual void finished() override;
void failInvalidFieldUnderObject(const StringView &fieldName) const;
+ void validatePackageTypeDefined() const;
private:
void parsePlatformConfigs(const StringView &fieldName, const ConfigValue &fieldValue);
void parsePlatformConfig(const StringView &fieldName, const ConfigValue &fieldValue);
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 75fdd02..f8b53e3 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -7,6 +7,8 @@ using u8string = utf8::unchecked::iterator<char*>;
namespace sibs
{
+ static const string EMPTY_STRING = "";
+
class UnexpectedTokenException : public std::runtime_error
{
public:
@@ -458,6 +460,14 @@ namespace sibs
{
return defines;
}
+
+ const string& SibsConfig::getDefinedValue(const string &name) const
+ {
+ auto it = defines.find(name);
+ if(it != defines.end())
+ return it->second;
+ return EMPTY_STRING;
+ }
void getLibFiles(const string &libPath, vector<string> &outputFiles)
{
@@ -723,6 +733,53 @@ namespace sibs
else
throw ParserException("Expected field under define to be a single value, was a list");
}
+ else if(currentObject.equals("define.static"))
+ {
+ // TODO: Do same for cmake args and other objects where you have static and dynamic.
+ // Makes it easier to handle config (no need for switch for different libraryTypes)
+ validatePackageTypeDefined();
+
+ if(value.isSingle())
+ {
+ if(packageType == PackageType::STATIC)
+ {
+ if(!isValidCIdentifier(name))
+ {
+ string errMsg = "Definition \"";
+ errMsg.append(name.data, name.size);
+ errMsg += "\" is not in a valid format. The first character have to match [a-zA-Z_] and the next characters have to match [a-zA-Z0-9_]";
+ throw ParserException(errMsg);
+ }
+ defines[string(name.data, name.size)] = string(value.asSingle().data, value.asSingle().size);
+ }
+ }
+ else
+ throw ParserException("Expected field under define.static to be a single value, was a list");
+ }
+ else if(currentObject.equals("define.dynamic"))
+ {
+ validatePackageTypeDefined();
+
+ if(value.isSingle())
+ {
+ // TODO: Remove `LIBRARY` from PackageType and if building a project where type is `library`,
+ // then convert it to dynamic. If a dependency has type `library`, then convert to dynamic
+ // unless build option includes to build dependencies as static libraries
+ if(packageType == PackageType::DYNAMIC || packageType == PackageType::LIBRARY)
+ {
+ if(!isValidCIdentifier(name))
+ {
+ string errMsg = "Definition \"";
+ errMsg.append(name.data, name.size);
+ errMsg += "\" is not in a valid format. The first character have to match [a-zA-Z_] and the next characters have to match [a-zA-Z0-9_]";
+ throw ParserException(errMsg);
+ }
+ defines[string(name.data, name.size)] = string(value.asSingle().data, value.asSingle().size);
+ }
+ }
+ else
+ throw ParserException("Expected field under define.dynamic to be a single value, was a list");
+ }
else if(currentObject.equals("cmake"))
{
parseCmake(name, value, cmakeDirGlobal, cmakeArgsGlobal);
@@ -947,6 +1004,12 @@ namespace sibs
throw ParserException(errMsg);
}
+ void SibsConfig::validatePackageTypeDefined() const
+ {
+ if((int)packageType == -1)
+ throw ParserException("package.type type has not been defined yet. Expected to be either 'executable', 'static', 'dynamic' or 'library'");
+ }
+
void SibsTestConfig::processObject(StringView name)
{
currentObject = name;
diff --git a/src/main.cpp b/src/main.cpp
index c626f11..f4d022e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -55,6 +55,8 @@ using namespace std::chrono;
// and should this force static compilation so dependencies can also be built with protection and if dependencies dont exist
// as static library/source, then fail build?
+// TODO: Add support for common package managers (in distros). If package with the dependency version exists in package manager, install and use it instead
+
#if OS_FAMILY == OS_FAMILY_POSIX
#define ferr std::cerr
#else
diff --git a/tests/src/confTest/confTest.cpp b/tests/src/confTest/confTest.cpp
index 44bcab0..f3d9e2b 100644
--- a/tests/src/confTest/confTest.cpp
+++ b/tests/src/confTest/confTest.cpp
@@ -74,3 +74,33 @@ TEST_CASE("parse config - use different config for different platforms")
#endif
#endif
}
+
+TEST_CASE("parse config - define static")
+{
+ SibsConfig sibsConfig(Compiler::GCC, TINYDIR_STRING("tests/src/confTest"), OPT_LEV_DEBUG, false);
+ Result<bool> result = Config::readFromFile(TINYDIR_STRING("tests/src/confTest/defineStatic.conf"), sibsConfig);
+ if(result.isErr())
+ {
+ fprintf(stderr, "%s", result.getErrMsg().c_str());
+ exit(1);
+ }
+
+ REQUIRE(sibsConfig.getDefinedValue("GLOBAL_DEFINE") == "1");
+ REQUIRE(sibsConfig.getDefinedValue("BUILD_STATIC") == "1");
+ REQUIRE(sibsConfig.getDefinedValue("DEFINE_TYPE") == "STATIC");
+}
+
+TEST_CASE("parse config - define dynamic")
+{
+ SibsConfig sibsConfig(Compiler::GCC, TINYDIR_STRING("tests/src/confTest"), OPT_LEV_DEBUG, false);
+ Result<bool> result = Config::readFromFile(TINYDIR_STRING("tests/src/confTest/defineDynamic.conf"), sibsConfig);
+ if(result.isErr())
+ {
+ fprintf(stderr, "%s", result.getErrMsg().c_str());
+ exit(1);
+ }
+
+ REQUIRE(sibsConfig.getDefinedValue("GLOBAL_DEFINE") == "1");
+ REQUIRE(sibsConfig.getDefinedValue("BUILD_STATIC") == "0");
+ REQUIRE(sibsConfig.getDefinedValue("DEFINE_TYPE") == "DYNAMIC");
+}
diff --git a/tests/src/confTest/defineDynamic.conf b/tests/src/confTest/defineDynamic.conf
new file mode 100644
index 0000000..fb08e5c
--- /dev/null
+++ b/tests/src/confTest/defineDynamic.conf
@@ -0,0 +1,17 @@
+[package]
+name = "glew"
+version = "2.1.0"
+type = "dynamic"
+platforms = ["any"]
+
+[define]
+GLOBAL_DEFINE = "1"
+DEFINE_TYPE = "GLOBAL"
+
+[define.static]
+BUILD_STATIC = "1"
+DEFINE_TYPE = "STATIC"
+
+[define.dynamic]
+BUILD_STATIC = "0"
+DEFINE_TYPE = "DYNAMIC"
diff --git a/tests/src/confTest/defineStatic.conf b/tests/src/confTest/defineStatic.conf
new file mode 100644
index 0000000..8ec0d8c
--- /dev/null
+++ b/tests/src/confTest/defineStatic.conf
@@ -0,0 +1,17 @@
+[package]
+name = "glew"
+version = "2.1.0"
+type = "static"
+platforms = ["any"]
+
+[define]
+GLOBAL_DEFINE = "1"
+DEFINE_TYPE = "GLOBAL"
+
+[define.static]
+BUILD_STATIC = "1"
+DEFINE_TYPE = "STATIC"
+
+[define.dynamic]
+BUILD_STATIC = "0"
+DEFINE_TYPE = "DYNAMIC"