aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-10-10 07:59:51 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-06 07:39:33 +0200
commit7c24c5d0de4d3584d6d2f9f3c26b4d757b0a0df2 (patch)
tree81585a1be9126c4bc1be946e74b4b6e1d706279b
parent6b238d4bc3c142f6337a73d858e069cae778dc54 (diff)
Fix sibs test not including parent library correctly
Refactor config parsing to reduce number of changes when introducing a new platform to support
-rw-r--r--backend/BackendUtils.cpp2
-rw-r--r--backend/ninja/Ninja.cpp264
-rw-r--r--backend/ninja/Ninja.hpp10
-rw-r--r--include/Conf.hpp139
-rw-r--r--include/Platform.hpp17
-rw-r--r--include/StringView.hpp7
-rw-r--r--src/Conf.cpp190
-rw-r--r--src/Platform.cpp38
-rw-r--r--src/main.cpp4
-rw-r--r--tests/src/confTest/confTest.cpp12
-rw-r--r--tests/src/confTest/linux/x86/static/debug/libcool.a0
-rw-r--r--tests/src/confTest/linux/x86/static/release/libcool.a0
12 files changed, 335 insertions, 348 deletions
diff --git a/backend/BackendUtils.cpp b/backend/BackendUtils.cpp
index d5fad04..b724f51 100644
--- a/backend/BackendUtils.cpp
+++ b/backend/BackendUtils.cpp
@@ -91,7 +91,7 @@ namespace backend
if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath()))
{
string filePathUtf8 = toUtf8(pathNative.c_str());
- ninjaProject->addTestSourceDir(filePathUtf8.c_str());
+ ninjaProject->setTestSourceDir(filePathUtf8.c_str());
}
else if(recursive && !directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs()) && _tinydir_strcmp(file->name, TINYDIR_STRING("sibs-build")) != 0)
{
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index ef6c365..3a2fa0f 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -252,11 +252,11 @@ namespace backend
sourceFiles.push_back({ language, filePathStr });
}
- void Ninja::addTestSourceDir(const char *dir)
+ void Ninja::setTestSourceDir(const char *dir)
{
string dirStr = dir ? dir : "";
- if(dir && !containsTestSourceDir(dirStr))
- testSourceDirs.emplace_back(dirStr);
+ if(dir)
+ testSourceDir = dirStr;
}
void Ninja::addDependency(const std::string &binaryFile)
@@ -264,6 +264,12 @@ namespace backend
if(!containsDependency(binaryFile))
binaryDependencies.emplace_back(binaryFile);
}
+
+ void Ninja::addDynamicDependency(const std::string &dependency)
+ {
+ if(!containsDynamicDependency(dependency))
+ dynamicDependencies.push_back(dependency);
+ }
void Ninja::addSubProject(Ninja *subProject, SibsConfig *config, sibs::FileString &&buildPath)
{
@@ -285,21 +291,21 @@ namespace backend
return false;
}
- bool Ninja::containsTestSourceDir(const string &dir) const
+ bool Ninja::containsDependency(const string &dependency) const
{
- for(const string &testSourceDir : testSourceDirs)
+ for(const string &binaryDependency : binaryDependencies)
{
- if(testSourceDir == dir)
+ if(binaryDependency == dependency)
return true;
}
return false;
}
- bool Ninja::containsDependency(const string &dependency) const
+ bool Ninja::containsDynamicDependency(const std::string &dependency) const
{
- for(const string &binaryDependency : binaryDependencies)
+ for(const string &dynamicDependency : dynamicDependencies)
{
- if(binaryDependency == dependency)
+ if(dynamicDependency == dependency)
return true;
}
return false;
@@ -672,32 +678,41 @@ namespace backend
return filepath.substr(0, it.base().base() - &filepath[0]);
}
- static string extractDynamicLibDirsFromLinkerFlags(const vector<string> &linkerFlags)
+ static string extractDynamicLibDirsFromLinkerFlag(const string &linkerFlag)
{
string result;
- for(const string &flag : linkerFlags)
+
+ FileString flagNative;
+ if(linkerFlag.size() >= 2 && (linkerFlag[0] == '\'' || linkerFlag[0] == '"') && (linkerFlag.back() == '\'' || linkerFlag.back() == '"'))
+ flagNative = toFileString(StringView(&linkerFlag[1], linkerFlag.size() - 2));
+ else
+ flagNative = toFileString(linkerFlag);
+
+ if(getFileType(flagNative.c_str()) == FileType::REGULAR)
{
- FileString flagNative;
- if(flag.size() >= 2 && (flag[0] == '\'' || flag[0] == '"') && (flag.back() == '\'' || flag.back() == '"'))
- flagNative = toFileString(StringView(&flag[1], flag.size() - 2));
- else
- flagNative = toFileString(flag);
-
- if(getFileType(flagNative.c_str()) == FileType::REGULAR)
+ Result<FileString> libFullPath = getRealPath(flagNative.c_str());
+ if(libFullPath)
{
- Result<FileString> libFullPath = getRealPath(flagNative.c_str());
- if(libFullPath)
+ FileString libDir = getFileParentDirectory(libFullPath.unwrap());
+ if(!libDir.empty())
{
- FileString libDir = getFileParentDirectory(libFullPath.unwrap());
- if(!libDir.empty())
- {
- if(!result.empty());
- result += ":";
- result += toUtf8(libDir);
- }
+ result = toUtf8(libDir);
}
}
}
+
+ return result;
+ }
+
+ static string extractDynamicLibDirsFromLinkerFlags(const vector<string> &linkerFlags)
+ {
+ string result;
+ for(const string &flag : linkerFlags)
+ {
+ if(!result.empty())
+ result += ":";
+ result += extractDynamicLibDirsFromLinkerFlag(flag);
+ }
return result;
}
@@ -866,6 +881,11 @@ namespace backend
dynamicLinkerFlags.push_back(linkerFlag);
};
}
+
+ for(const string &dynamicDependency : dynamicDependencies)
+ {
+ dynamicLinkerFlagCallback(dynamicDependency);
+ }
vector<ninja::NinjaArg> cflags;
auto cflagsCallbackFunc = [&cflags](const string &dependencyCflags)
@@ -1256,7 +1276,9 @@ namespace backend
// TODO: For now zig projects (zig object files) are built with c/c++ compiler,
// they should be built with zig if project only contains zig files.
// But how to combine object files with zig? build-exe only wants to accept .zig files
- string projectGeneratedBinaryFlags;
+ string projectGeneratedBinary = "\"";
+ projectGeneratedBinary += savePathUtf8;
+ projectGeneratedBinary += "/";
if (!sourceFiles.empty() && !zigTest)
{
string noUndefinedFlag;
@@ -1268,10 +1290,6 @@ namespace backend
noUndefinedFlag = isCCompilerClang ? "-Wl,-undefined,error" : "-Wl,--no-undefined,--as-needed";
}
- string projectGeneratedBinary = "\"";
- projectGeneratedBinary += savePathUtf8;
- projectGeneratedBinary += "/";
-
ninja::NinjaVariable zigObjectArgs("object_args");
string objectZigArgs;
if(onlyZigFiles)
@@ -1633,8 +1651,6 @@ namespace backend
assert(false);
return Result<bool>::Err("Unexpected error");
}
-
- projectGeneratedBinaryFlags = allLinkerFlags + " " + projectGeneratedBinary;
}
if(!sourceFiles.empty())
@@ -1656,16 +1672,16 @@ namespace backend
}
}
- Result<bool> buildTestResult = buildTests(projectGeneratedBinaryFlags, config, savePath, dependencyExportIncludeDirs);
+ Result<bool> buildTestResult = buildTests(allLinkerFlags, projectGeneratedBinary, config, savePath, dependencyExportIncludeDirs);
if(!buildTestResult)
return buildTestResult;
return Result<bool>::Ok(true);
}
- Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinaryFlags, const SibsConfig &config, const _tinydir_char_t *savePath, const string &parentDependencyExportIncludeDirs)
+ Result<bool> Ninja::buildTests(const std::string &parentLinkerFlags, const std::string &parentGeneratedLib, const SibsConfig &config, const _tinydir_char_t *savePath, const string &parentDependencyExportIncludeDirs)
{
- if(testSourceDirs.empty() || !config.shouldBuildTests())
+ if(testSourceDir.empty() || !config.shouldBuildTests())
return Result<bool>::Ok(true);
assert(getNinjaLibraryType(config.getPackageType()) != LibraryType::EXECUTABLE);
@@ -1682,105 +1698,115 @@ namespace backend
parentExportIncludeDirs += getIncludeOptionFlag(config.getCompiler(), parentExportIncludeDir);
}
- for(const string &testSourceDir : testSourceDirs)
- {
#if OS_FAMILY == OS_FAMILY_POSIX
- FileString testSourceDirNative = testSourceDir;
- FileString projectConfFilePath = testSourceDir;
+ FileString testSourceDirNative = testSourceDir;
+ FileString projectConfFilePath = testSourceDir;
#else
- FileString testSourceDirNative = utf8To16(testSourceDir);
- FileString projectConfFilePath = testSourceDirNative;
+ FileString testSourceDirNative = utf8To16(testSourceDir);
+ FileString projectConfFilePath = testSourceDirNative;
#endif
- projectConfFilePath += TINYDIR_STRING("/project.conf");
-
- FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
- SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative, config.getOptimizationLevel());
- sibsTestConfig.platform = config.platform;
- sibsTestConfig.setSanitize(config.getSanitize());
- sibsTestConfig.zigTestFiles = move(config.zigTestFiles);
- sibsTestConfig.zigTestAllFiles = config.zigTestAllFiles;
- if(projectConfFileType == FileType::REGULAR)
- {
- Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig);
- if(!result)
- return result;
- }
+ projectConfFilePath += TINYDIR_STRING("/project.conf");
+
+ FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
+ SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative, config.getOptimizationLevel());
+ sibsTestConfig.platform = config.platform;
+ sibsTestConfig.setSanitize(config.getSanitize());
+ sibsTestConfig.zigTestFiles = move(config.zigTestFiles);
+ sibsTestConfig.zigTestAllFiles = config.zigTestAllFiles;
+ if(projectConfFileType == FileType::REGULAR)
+ {
+ Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig);
+ if(!result)
+ return result;
+ }
+
+ backend::Ninja ninja;
+ ninja.addGlobalIncludeDirs(parentExportIncludeDirs);
+ if(!parentLinkerFlags.empty())
+ ninja.addDependency(parentLinkerFlags);
- backend::Ninja ninja;
- ninja.addGlobalIncludeDirs(parentExportIncludeDirs);
- if(!projectGeneratedBinaryFlags.empty())
- ninja.addDependency(projectGeneratedBinaryFlags);
+ switch(config.getPackageType())
+ {
+ case PackageType::STATIC:
+ ninja.addDependency(parentGeneratedLib);
+ break;
+ case PackageType::LIBRARY:
+ case PackageType::DYNAMIC:
+ ninja.addDynamicDependency(parentGeneratedLib);
+ break;
+ default:
+ break;
+ }
- bool zigTest = false;
- if(config.zigTestAllFiles)
+ bool zigTest = false;
+ if(config.zigTestAllFiles)
+ {
+ backend::BackendUtils::collectSourceFiles(testSourceDirNative.c_str(), &ninja, sibsTestConfig);
+ // TODO: This can be optimized as well. No need to insert non-zig files if we are going to remove them.
+ // Maybe pass a filter callback function to @collectSourceFiles.
+ for(auto it = ninja.sourceFiles.begin(); it != ninja.sourceFiles.end(); )
{
- backend::BackendUtils::collectSourceFiles(testSourceDirNative.c_str(), &ninja, sibsTestConfig);
- // TODO: This can be optimized as well. No need to insert non-zig files if we are going to remove them.
- // Maybe pass a filter callback function to @collectSourceFiles.
- for(auto it = ninja.sourceFiles.begin(); it != ninja.sourceFiles.end(); )
+ if(it->language != sibs::Language::ZIG)
{
- if(it->language != sibs::Language::ZIG)
- {
- it = ninja.sourceFiles.erase(it);
- }
- else
- {
- ++it;
- }
+ it = ninja.sourceFiles.erase(it);
}
- zigTest = true;
- }
- else if(!config.zigTestFiles.empty())
- {
- ninja.sourceFiles.reserve(config.zigTestFiles.size());
- for(const sibs::FileString &testFile : config.zigTestFiles)
+ else
{
- ninja.addSourceFile(sibs::Language::ZIG, toUtf8(testFile.c_str()).c_str());
+ ++it;
}
- zigTest = true;
}
- else
+ zigTest = true;
+ }
+ else if(!config.zigTestFiles.empty())
+ {
+ ninja.sourceFiles.reserve(config.zigTestFiles.size());
+ for(const sibs::FileString &testFile : config.zigTestFiles)
{
- backend::BackendUtils::collectSourceFiles(testSourceDirNative.c_str(), &ninja, sibsTestConfig);
+ ninja.addSourceFile(sibs::Language::ZIG, toUtf8(testFile.c_str()).c_str());
}
+ zigTest = true;
+ }
+ else
+ {
+ backend::BackendUtils::collectSourceFiles(testSourceDirNative.c_str(), &ninja, sibsTestConfig);
+ }
- if(!ninja.getSourceFiles().empty())
+ if(!ninja.getSourceFiles().empty())
+ {
+ FileString buildPath = testSourceDirNative;
+ switch(sibsTestConfig.getOptimizationLevel())
{
- FileString buildPath = testSourceDirNative;
- switch(sibsTestConfig.getOptimizationLevel())
- {
- case OPT_LEV_DEBUG:
- buildPath += TINYDIR_STRING("/sibs-build/debug");
- break;
- case OPT_LEV_RELEASE:
- buildPath += TINYDIR_STRING("/sibs-build/release");
- break;
- }
-
- Result<bool> buildFileResult = ninja.build(sibsTestConfig, buildPath.c_str());
- if (!buildFileResult)
+ case OPT_LEV_DEBUG:
+ buildPath += TINYDIR_STRING("/sibs-build/debug");
+ break;
+ case OPT_LEV_RELEASE:
+ buildPath += TINYDIR_STRING("/sibs-build/release");
+ break;
+ }
+
+ Result<bool> buildFileResult = ninja.build(sibsTestConfig, buildPath.c_str());
+ if (!buildFileResult)
+ return buildFileResult;
+
+ // Main projects test should also have compilation database, so we can use it inside IDE
+ if(config.isMainProject())
+ {
+ buildFileResult = buildCompilationDatabase(buildPath.c_str(), testSourceDirNative);
+ if(!buildFileResult)
return buildFileResult;
-
- // Main projects test should also have compilation database, so we can use it inside IDE
- if(config.isMainProject())
- {
- buildFileResult = buildCompilationDatabase(buildPath.c_str(), testSourceDirNative);
- if(!buildFileResult)
- return buildFileResult;
- }
+ }
- if(!zigTest)
- {
- FileString testExecutableName = buildPath;
- testExecutableName += TINYDIR_STRING("/");
- testExecutableName += toFileString(sibsTestConfig.getPackageName());
- Result<ExecResult> runTestResult = exec(testExecutableName.c_str(), true);
- if(!runTestResult)
- return Result<bool>::Err(runTestResult);
-
- if(runTestResult.unwrap().exitCode != 0)
- return Result<bool>::Err("Tests failed", runTestResult.unwrap().exitCode);
- }
+ if(!zigTest)
+ {
+ FileString testExecutableName = buildPath;
+ testExecutableName += TINYDIR_STRING("/");
+ testExecutableName += toFileString(sibsTestConfig.getPackageName());
+ Result<ExecResult> runTestResult = exec(testExecutableName.c_str(), true);
+ if(!runTestResult)
+ return Result<bool>::Err(runTestResult);
+
+ if(runTestResult.unwrap().exitCode != 0)
+ return Result<bool>::Err("Tests failed", runTestResult.unwrap().exitCode);
}
}
diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp
index 8606708..2928fb3 100644
--- a/backend/ninja/Ninja.hpp
+++ b/backend/ninja/Ninja.hpp
@@ -43,25 +43,27 @@ namespace backend
void addGlobalIncludeDirs(const std::string &globalIncludeDirs);
void addSourceFile(sibs::Language language, const char *filepath);
- void addTestSourceDir(const char *dir);
+ void setTestSourceDir(const char *dir);
void addDependency(const std::string &binaryFile);
+ void addDynamicDependency(const std::string &dependency);
void addSubProject(Ninja *subProject, sibs::SibsConfig *config, sibs::FileString &&buildPath);
const std::vector<sibs::SourceFile>& getSourceFiles() const;
sibs::Result<bool> build(const sibs::SibsConfig &config, const _tinydir_char_t *savePath, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc = nullptr, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback = nullptr, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback = nullptr);
private:
sibs::Result<bool> buildSubProjects(sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback);
- sibs::Result<bool> buildTests(const std::string &projectGeneratedBinaryFlags, const sibs::SibsConfig &config, const _tinydir_char_t *savePath, const std::string &parentDependencyExportIncludeDirs);
+ sibs::Result<bool> buildTests(const std::string &parentLinkerFlags, const std::string &parentGeneratedLib, const sibs::SibsConfig &config, const _tinydir_char_t *savePath, const std::string &parentDependencyExportIncludeDirs);
bool containsSourceFile(const std::string &filepath) const;
- bool containsTestSourceDir(const std::string &dir) const;
bool containsDependency(const std::string &dependency) const;
+ bool containsDynamicDependency(const std::string &dependency) const;
sibs::Result<bool> getLinkerFlags(const sibs::SibsConfig &config, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback, sibs::GlobalIncludeDirCallbackFunc globalIncludeDirCallback, sibs::CflagsCallbackFunc cflagsCallbackFunc) const;
sibs::Result<bool> compile(const _tinydir_char_t *buildFilePath);
sibs::Result<bool> buildCompilationDatabase(const _tinydir_char_t *buildFilePath, const sibs::FileString &savePath);
private:
std::string customGlobalIncludeDirs;
+ std::string testSourceDir;
std::vector<sibs::SourceFile> sourceFiles;
- std::vector<std::string> testSourceDirs;
std::vector<std::string> binaryDependencies;
+ std::vector<std::string> dynamicDependencies;
std::vector<NinjaSubProject> subProjects;
};
}
diff --git a/include/Conf.hpp b/include/Conf.hpp
index bae0153..a60bc36 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -138,181 +138,47 @@ namespace sibs
Language language;
std::string filepath;
};
-
- const StringView CONFIGS[] = {
- "config.win",
- "config.win.static.debug",
- "config.win.static.release",
-
- "config.linux",
- "config.linux.static.debug",
- "config.linux.static.release",
-
- "config.macos",
- "config.macos.static.debug",
- "config.macos.static.release",
-
- "config.bsd",
- "config.bsd.static.debug",
- "config.bsd.static.release",
-
- "config.openbsd",
- "config.openbsd.static.debug",
- "config.openbsd.static.release",
-
- "config.haiku",
- "config.haiku.static.debug",
- "config.haiku.static.release",
-
- "config.win32",
- "config.win32.static.debug",
- "config.win32.static.release",
-
- "config.win64",
- "config.win64.static.debug",
- "config.win64.static.release",
-
- "config.linux32",
- "config.linux32.static.debug",
- "config.linux32.static.release",
-
- "config.linux64",
- "config.linux64.static.debug",
- "config.linux64.static.release",
-
- "config.macos32",
- "config.macos32.static.debug",
- "config.macos32.static.release"
-
- "config.macos64",
- "config.macos64.static.debug",
- "config.macos64.static.release",
-
- "config.openbsd32",
- "config.openbsd32.static.debug",
- "config.openbsd32.static.release",
-
- "config.openbsd64",
- "config.openbsd64.static.debug",
- "config.openbsd64.static.release",
-
- "config.haiku32",
- "config.haiku32.static.debug",
- "config.haiku32.static.release",
-
- "config.haiku64",
- "config.haiku64.static.debug",
- "config.haiku64.static.release"
- };
- const int NUM_CONFIGS = 3 * 16;
- const int CONFIGS_GENERIC_OFFSET = 3 * 6;
#if OS_TYPE == OS_TYPE_WINDOWS
#ifdef SIBS_ENV_32BIT
const Platform SYSTEM_PLATFORM = PLATFORM_WIN32;
- #define SYSTEM_PLATFORM_NAME L"win32"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 0
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 1
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 2
#else
const Platform SYSTEM_PLATFORM = PLATFORM_WIN64;
- #define SYSTEM_PLATFORM_NAME L"win64"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 3
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 4
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 5
#endif
#define CONFIG_STATIC_LIB_FILE_EXTENSION L"lib"
#define CONFIG_DYNAMIC_LIB_FILE_EXTENSION L"dll"
-
- #define SYSTEM_GENERIC_PLATFORM_NAME "win"
- #define CONFIG_GENERIC_SYSTEM_PLATFORM 0
- #define CONFIG_GENERIC_STATIC_DEBUG_PLATFORM 1
- #define CONFIG_GENERIC_STATIC_RELEASE_PLATFORM 2
#elif OS_TYPE == OS_TYPE_LINUX
#ifdef SIBS_ENV_32BIT
const Platform SYSTEM_PLATFORM = PLATFORM_LINUX32;
- #define SYSTEM_PLATFORM_NAME "linux32"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 6
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 7
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 8
#else
const Platform SYSTEM_PLATFORM = PLATFORM_LINUX64;
- #define SYSTEM_PLATFORM_NAME "linux64"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 9
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 10
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 11
#endif
#define CONFIG_STATIC_LIB_FILE_EXTENSION "a"
#define CONFIG_DYNAMIC_LIB_FILE_EXTENSION "so"
-
- #define SYSTEM_GENERIC_PLATFORM_NAME "linux"
- #define CONFIG_GENERIC_SYSTEM_PLATFORM 3
- #define CONFIG_GENERIC_STATIC_DEBUG_PLATFORM 4
- #define CONFIG_GENERIC_STATIC_RELEASE_PLATFORM 5
#elif OS_TYPE == OS_TYPE_APPLE
#ifdef SIBS_ENV_32BIT
const Platform SYSTEM_PLATFORM = PLATFORM_MACOS32;
- #define SYSTEM_PLATFORM_NAME "macos32"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 12
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 13
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 14
#else
const Platform SYSTEM_PLATFORM = PLATFORM_MACOS64;
- #define SYSTEM_PLATFORM_NAME "macos64"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 15
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 16
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 17
#endif
#define CONFIG_STATIC_LIB_FILE_EXTENSION "a"
#define CONFIG_DYNAMIC_LIB_FILE_EXTENSION "dylib"
-
- #define SYSTEM_GENERIC_PLATFORM_NAME "macos"
- #define CONFIG_GENERIC_SYSTEM_PLATFORM 6
- #define CONFIG_GENERIC_STATIC_DEBUG_PLATFORM 7
- #define CONFIG_GENERIC_STATIC_RELEASE_PLATFORM 8
#elif OS_TYPE == OS_TYPE_OPENBSD
#ifdef SIBS_ENV_32BIT
const Platform SYSTEM_PLATFORM = PLATFORM_OPENBSD32;
- #define SYSTEM_PLATFORM_NAME "openbsd32"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 18
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 19
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 20
#else
const Platform SYSTEM_PLATFORM = PLATFORM_OPENBSD64;
- #define SYSTEM_PLATFORM_NAME "openbsd64"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 21
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 22
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 23
#endif
#define CONFIG_STATIC_LIB_FILE_EXTENSION "a"
#define CONFIG_DYNAMIC_LIB_FILE_EXTENSION "so"
-
- // TODO: Also add "bsd" platform
- #define SYSTEM_GENERIC_PLATFORM_NAME "openbsd"
- #define CONFIG_GENERIC_SYSTEM_PLATFORM 12
- #define CONFIG_GENERIC_STATIC_DEBUG_PLATFORM 13
- #define CONFIG_GENERIC_STATIC_RELEASE_PLATFORM 14
#elif OS_TYPE == OS_TYPE_HAIKU
#ifdef SIBS_ENV_32BIT
const Platform SYSTEM_PLATFORM = PLATFORM_HAIKU32;
- #define SYSTEM_PLATFORM_NAME "haiku32"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 24
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 25
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 26
#else
const Platform SYSTEM_PLATFORM = PLATFORM_HAIKU64;
- #define SYSTEM_PLATFORM_NAME "haiku64"
- #define CONFIG_SYSTEM_PLATFORM CONFIGS_GENERIC_OFFSET + 27
- #define CONFIG_STATIC_DEBUG_PLATFORM CONFIGS_GENERIC_OFFSET + 28
- #define CONFIG_STATIC_RELEASE_PLATFORM CONFIGS_GENERIC_OFFSET + 29
#endif
#define CONFIG_STATIC_LIB_FILE_EXTENSION "a"
#define CONFIG_DYNAMIC_LIB_FILE_EXTENSION "so"
-
- #define SYSTEM_GENERIC_PLATFORM_NAME "haiku"
- #define CONFIG_GENERIC_SYSTEM_PLATFORM 15
- #define CONFIG_GENERIC_STATIC_DEBUG_PLATFORM 16
- #define CONFIG_GENERIC_STATIC_RELEASE_PLATFORM 17
#endif
const char* asString(OptimizationLevel optLevel);
@@ -365,13 +231,11 @@ namespace sibs
virtual const std::string& getPackageName() const
{
- assert(finishedProcessing);
return packageName;
}
virtual PackageType getPackageType() const
{
- assert(finishedProcessing);
return packageType;
}
@@ -543,6 +407,7 @@ namespace sibs
protected:
virtual void processObject(StringView name) override;
virtual void processField(StringView name, const ConfigValue &value) override;
+ void parseConfig(const StringView &name, const ConfigValue &value);
void parseDependencies(const StringView &name, const ConfigValue &value);
virtual void finished() override;
void failInvalidFieldUnderObject(const StringView &fieldName) const;
@@ -550,7 +415,7 @@ namespace sibs
private:
void parseCLang(const StringView &fieldName, const ConfigValue &fieldValue);
void parseCppLang(const StringView &fieldName, const ConfigValue &fieldValue);
- void parsePlatformBuildTypeConfigs(const StringView &fieldName, const ConfigValue &fieldValue);
+ void parsePlatformConfig(const StringView &fieldName, const ConfigValue &fieldValue);
std::string parsePlatformConfigStatic(const StringView &fieldName, const ConfigValue &fieldValue);
void parsePlatformConfigStaticDebug(const StringView &fieldName, const ConfigValue &fieldValue);
void parsePlatformConfigStaticRelease(const StringView &fieldName, const ConfigValue &fieldValue);
diff --git a/include/Platform.hpp b/include/Platform.hpp
index ffe7038..3ae3d24 100644
--- a/include/Platform.hpp
+++ b/include/Platform.hpp
@@ -29,9 +29,9 @@ namespace sibs
PLATFORM_OPENBSD32 = 1 << 12 | PLATFORM_OPENBSD,
PLATFORM_OPENBSD64 = 1 << 13 | PLATFORM_OPENBSD,
- PLATFORM_HAIKU = 1 << 20,
- PLATFORM_HAIKU32 = 1 << 21 | PLATFORM_HAIKU,
- PLATFORM_HAIKU64 = 1 << 22 | PLATFORM_HAIKU
+ PLATFORM_HAIKU = 1 << 20,
+ PLATFORM_HAIKU32 = 1 << 21 | PLATFORM_HAIKU,
+ PLATFORM_HAIKU64 = 1 << 22 | PLATFORM_HAIKU
};
const StringViewMap<Platform> PLATFORM_BY_NAME = {
@@ -49,13 +49,18 @@ namespace sibs
{ "openbsd", PLATFORM_OPENBSD },
{ "openbsd32", PLATFORM_OPENBSD32 },
{ "openbsd64", PLATFORM_OPENBSD64 },
- { "haiku", PLATFORM_HAIKU },
- { "haiku32", PLATFORM_HAIKU32 },
- { "haiku64", PLATFORM_HAIKU64 },
+ { "haiku", PLATFORM_HAIKU },
+ { "haiku32", PLATFORM_HAIKU32 },
+ { "haiku64", PLATFORM_HAIKU64 },
};
bool containsPlatform(const std::vector<Platform> &platforms, Platform platform);
const char* asString(Platform platform);
Platform getPlatformByName(StringView name);
+ // Return true if both platforms are of same type, for example if platform @a is either win, win32, win64 and @b is either win, win32, win64
bool isSamePlatformFamily(Platform a, Platform b);
+ // Returns true if platform @base is a base platform for platform @platform, for example if @platform is win64 and @base is either win64 or win, then this function return true.
+ // If for example @platform is win64 and @base is win32, then this function returns false.
+ bool isBaseForPlatform(Platform base, Platform platform);
+ Platform getPlatformGenericType(Platform platform);
}
diff --git a/include/StringView.hpp b/include/StringView.hpp
index adfa237..4d87d8a 100644
--- a/include/StringView.hpp
+++ b/include/StringView.hpp
@@ -7,6 +7,7 @@
#include "env.hpp"
#include <cstring>
#include <unordered_map>
+#include <cassert>
namespace sibs
{
@@ -47,6 +48,12 @@ namespace sibs
return XXH32(data, size, 0xdec05eba);
#endif
}
+
+ char operator [] (size_t index) const
+ {
+ assert(index < size);
+ return data[index];
+ }
const char *data;
usize size;
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 38774e0..0307bc0 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -80,8 +80,12 @@ namespace sibs
char *startOfIdentifier = code.base();
++code;
c = *code;
+ char prevChar = '\0';
while(isIdentifierChar(c))
{
+ if(c == '.' && prevChar == '.')
+ throw UnexpectedTokenException("Identifier can't have two dots in a row");
+ prevChar = c;
++code;
c = *code;
}
@@ -863,59 +867,12 @@ namespace sibs
}
else if(currentObject.size >= 6 && strncmp(currentObject.data, "config", 6) == 0)
{
- bool platformConfig = currentObject.equals(CONFIGS[CONFIG_SYSTEM_PLATFORM]);
- if(currentObject.size == 6 || platformConfig) // [config]
+ if(currentObject.size == 6) // [config]
{
- 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(name.equals("include_dirs"))
- {
- if(value.isList())
- {
- for(const StringView &includeDir : value.asList())
- {
- includeDirs.emplace_back(string(includeDir.data, includeDir.size));
- }
- }
- else
- throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".include_dirs to be a list, was a single value");
- }
- else if(name.equals("ignore_dirs"))
- {
- if (value.isList())
- {
- string projectPathUtf8 = toUtf8(projectPath);
- for (const StringView &ignoreDir : value.asList())
- {
- string ignoreDirFull = projectPathUtf8;
- ignoreDirFull += "/";
- ignoreDirFull += string(ignoreDir.data, ignoreDir.size);
- ignoreDirs.emplace_back(move(ignoreDirFull));
- }
- }
- else
- throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".ignore_dirs to be a list, was a single value");
- }
- else
- failInvalidFieldUnderObject(name);
+ parseConfig(name, value);
}
else
- parsePlatformBuildTypeConfigs(name, value);
+ parsePlatformConfig(name, value);
}
else if(currentObject.equals("dependencies"))
{
@@ -1012,6 +969,57 @@ namespace sibs
throw ParserException(errMsg);
}
}
+
+ void SibsConfig::parseConfig(const StringView &name, const ConfigValue &value)
+ {
+ 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(name.equals("include_dirs"))
+ {
+ if(value.isList())
+ {
+ for(const StringView &includeDir : value.asList())
+ {
+ includeDirs.emplace_back(string(includeDir.data, includeDir.size));
+ }
+ }
+ else
+ throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".include_dirs to be a list, was a single value");
+ }
+ else if(name.equals("ignore_dirs"))
+ {
+ if (value.isList())
+ {
+ string projectPathUtf8 = toUtf8(projectPath);
+ for (const StringView &ignoreDir : value.asList())
+ {
+ string ignoreDirFull = projectPathUtf8;
+ ignoreDirFull += "/";
+ ignoreDirFull += string(ignoreDir.data, ignoreDir.size);
+ ignoreDirs.emplace_back(move(ignoreDirFull));
+ }
+ }
+ else
+ throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".ignore_dirs to be a list, was a single value");
+ }
+ else
+ failInvalidFieldUnderObject(name);
+ }
void SibsConfig::parseDependencies(const StringView &name, const ConfigValue &value)
{
@@ -1171,39 +1179,75 @@ namespace sibs
else
failInvalidFieldUnderObject(fieldName);
}
-
- void SibsConfig::parsePlatformBuildTypeConfigs(const StringView &fieldName, const ConfigValue &fieldValue)
+
+ static bool isObjectIdentifierSymbol(char c)
{
- bool validConfig = false;
- for(int i = 0; i < NUM_CONFIGS; ++i)
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '-';
+ }
+
+ static StringView getNextIdentifierInObject(const StringView &objectName)
+ {
+ size_t identifierStart = -1;
+ for(size_t i = 0; i < objectName.size; ++i)
{
- const StringView &config = CONFIGS[i];
- if(currentObject.equals(config))
+ char c = objectName[i];
+ if(c == '.')
{
- validConfig = true;
- switch(i)
- {
- case CONFIG_GENERIC_STATIC_DEBUG_PLATFORM:
- case CONFIG_STATIC_DEBUG_PLATFORM:
- parsePlatformConfigStaticDebug(fieldName, fieldValue);
- break;
- case CONFIG_GENERIC_STATIC_RELEASE_PLATFORM:
- case CONFIG_STATIC_RELEASE_PLATFORM:
- parsePlatformConfigStaticRelease(fieldName, fieldValue);
- break;
- default:
- break;
- }
+ if(identifierStart == -1)
+ identifierStart = i + 1;
+ else
+ return { objectName.data + identifierStart, i - identifierStart };
}
}
-
- if(!validConfig)
+
+ if(identifierStart == -1)
+ return { objectName.data + objectName.size, 0 };
+ else
+ return { objectName.data + identifierStart, objectName.size - identifierStart };
+ }
+
+ void SibsConfig::parsePlatformConfig(const StringView &fieldName, const ConfigValue &fieldValue)
+ {
+ StringView platformName = getNextIdentifierInObject(currentObject);
+ Platform platform = getPlatformByName(platformName);
+
+ if(platform == PLATFORM_INVALID)
{
string errMsg = "Invalid config object \"";
errMsg += string(currentObject.data, currentObject.size);
- errMsg += "\"";
+ errMsg += "\", invalid platform: ";
+ errMsg += string(platformName.data, platformName.size);
throw ParserException(errMsg);
}
+
+ if(!isBaseForPlatform(platform, SYSTEM_PLATFORM))
+ return;
+
+ const char *start = platformName.data + platformName.size;
+ const char *currentObjEnd = currentObject.data + currentObject.size;
+ if(start < currentObjEnd)
+ {
+ size_t size = currentObjEnd - start;
+ StringView platformConfigType = { start, size };
+
+ if(size == 13 && strncmp(platformConfigType.data, ".static.debug", 13) == 0)
+ {
+ parsePlatformConfigStaticDebug(fieldName, fieldValue);
+ }
+ else if(size == 15 && strncmp(platformConfigType.data, ".static.release", 15) == 0)
+ {
+ parsePlatformConfigStaticRelease(fieldName, fieldValue);
+ }
+ else
+ {
+ string errMsg = "Invalid config object \"";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += "\"";
+ throw ParserException(errMsg);
+ }
+ }
+ else
+ parseConfig(fieldName, fieldValue);
}
string SibsConfig::parsePlatformConfigStatic(const StringView &fieldName, const ConfigValue &fieldValue)
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 9b02ca5..dd81667 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -1,7 +1,31 @@
#include "../include/Platform.hpp"
+#include <cassert>
namespace sibs
{
+ static int countSetBits(u32 value)
+ {
+ int count = 0;
+ while(value)
+ {
+ count += (value & 1U);
+ value >>= 1U;
+ }
+ return count;
+ }
+
+ // Returns -1 if no bit is set
+ static int getLeastSignificantBitSetPosition(u32 value)
+ {
+ for(u32 i = 0; i < sizeof(u32); ++i)
+ {
+ if(value & 1U)
+ return i;
+ value >>= 1U;
+ }
+ return -1;
+ }
+
bool containsPlatform(const std::vector<Platform> &platforms, Platform platform)
{
for (Platform vecPlatform : platforms)
@@ -33,7 +57,7 @@ namespace sibs
case PLATFORM_HAIKU: return "haiku";
case PLATFORM_HAIKU32: return "haiku32";
case PLATFORM_HAIKU64: return "haiku64";
- default: return nullptr;
+ default: assert(false); return nullptr;
}
}
@@ -49,4 +73,16 @@ namespace sibs
{
return a & b;
}
+
+ bool isBaseForPlatform(Platform base, Platform platform)
+ {
+ return base == PLATFORM_ANY || base == platform || (isSamePlatformFamily(platform, base) && countSetBits(base) < countSetBits(platform));
+ }
+
+ Platform getPlatformGenericType(Platform platform)
+ {
+ if(platform == PLATFORM_INVALID || platform == PLATFORM_ANY)
+ return PLATFORM_INVALID;
+ return (Platform)(1U << (u32)getLeastSignificantBitSetPosition(platform));
+ }
}
diff --git a/src/main.cpp b/src/main.cpp
index b05cded..b3a8f40 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -503,7 +503,7 @@ static int buildProject(int argc, const _tinydir_char_t **argv)
optimizationLevel = OPT_LEV_DEBUG;
if(!platformName)
- platformName = SYSTEM_PLATFORM_NAME;
+ platformName = asString(SYSTEM_PLATFORM);
string platformUtf8 = toUtf8(platformName);
Platform platform = getPlatformByName(StringView(platformUtf8.data(), platformUtf8.size()));
@@ -718,7 +718,7 @@ static Result<bool> newProjectCreateConf(const string &projectName, const string
projectConfStr += "name = \"" + projectName + "\"\n";
projectConfStr += "type = \"" + projectType + "\"\n";
projectConfStr += "version = \"0.1.0\"\n";
- projectConfStr += "platforms = [\"" + string(SYSTEM_GENERIC_PLATFORM_NAME) + "\"]\n\n";
+ projectConfStr += "platforms = [\"" + string(asString(getPlatformGenericType(SYSTEM_PLATFORM))) + "\"]\n\n";
projectConfStr += "[dependencies]\n";
FileString projectConfPath = projectPath;
diff --git a/tests/src/confTest/confTest.cpp b/tests/src/confTest/confTest.cpp
index b5d5ae1..8dab691 100644
--- a/tests/src/confTest/confTest.cpp
+++ b/tests/src/confTest/confTest.cpp
@@ -83,11 +83,13 @@ TEST_CASE("parse config - use different config for different platforms")
}
#if OS_TYPE == OS_TYPE_LINUX and defined(SIBS_ENV_64BIT)
- #ifdef DEBUG
- REQUIRE(sibsConfig.getDebugStaticLibs()[0] == TINYDIR_STRING("tests/src/confTest/linux/x64/static/debug/libcool.a"));
- #else
- REQUIRE(sibsConfig.getDebugStaticLibs()[0] == TINYDIR_STRING("tests/src/confTest/linux/x64/static/release/libcool.a"));
- #endif
+ REQUIRE(sibsConfig.getDebugStaticLibs()[0] == TINYDIR_STRING("tests/src/confTest/linux/x64/static/debug/libcool.a"));
+ REQUIRE(sibsConfig.getReleaseStaticLibs()[0] == TINYDIR_STRING("tests/src/confTest/linux/x64/static/release/libcool.a"));
+ REQUIRE(sibsConfig.getGlobalIncludeDirs()[0] == "include_linux64");
+ #elif OS_TYPE == OS_TYPE_LINUX and defined(SIBS_ENV_32BIT)
+ REQUIRE(sibsConfig.getDebugStaticLibs()[0] == TINYDIR_STRING("tests/src/confTest/linux/x86/static/debug/libcool.a"));
+ REQUIRE(sibsConfig.getReleaseStaticLibs()[0] == TINYDIR_STRING("tests/src/confTest/linux/x86/static/release/libcool.a"));
+ REQUIRE(sibsConfig.getGlobalIncludeDirs()[0] == "include_linux32");
#endif
}
diff --git a/tests/src/confTest/linux/x86/static/debug/libcool.a b/tests/src/confTest/linux/x86/static/debug/libcool.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/src/confTest/linux/x86/static/debug/libcool.a
diff --git a/tests/src/confTest/linux/x86/static/release/libcool.a b/tests/src/confTest/linux/x86/static/release/libcool.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/src/confTest/linux/x86/static/release/libcool.a