diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-03-21 14:56:51 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2018-03-21 14:58:31 +0100 |
commit | 23117906c571714b0b55caf35cf9f876d1f9fa2e (patch) | |
tree | 21574306de1efb6eafd2af48f5188bf9e3550dd8 /src | |
parent | b44ff4ec7d2c2458aab04b5daf79134e5d284f6e (diff) |
Add sub projects (should be used with git submodules)
Fix issue where static lib dependencies are not built correctly because their
dynamic lib dependencies are not propagated to dependant project
Diffstat (limited to 'src')
-rw-r--r-- | src/CmakeModule.cpp | 13 | ||||
-rw-r--r-- | src/Conf.cpp | 57 | ||||
-rw-r--r-- | src/GlobalLib.cpp | 109 | ||||
-rw-r--r-- | src/main.cpp | 91 |
4 files changed, 89 insertions, 181 deletions
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp index 990bf36..eeb8a9c 100644 --- a/src/CmakeModule.cpp +++ b/src/CmakeModule.cpp @@ -53,12 +53,15 @@ namespace sibs } string dynamicLinkerFlags; - // TODO: If project contains no source files, then we shouldn't override this function - dynamicLinkerFlagCallbackFunc = [&dynamicLinkerFlags](const string &linkerFlag) + // TODO: If project contains no source files, then we shouldn't override this function... why? + if(!dynamicLinkerFlagCallbackFunc || config.getPackageType() != PackageType::STATIC) { - dynamicLinkerFlags += " "; - dynamicLinkerFlags += linkerFlag; - }; + dynamicLinkerFlagCallbackFunc = [&dynamicLinkerFlags](const string &linkerFlag) + { + dynamicLinkerFlags += " "; + dynamicLinkerFlags += linkerFlag; + }; + } // TODO: Create a cmake module that contains library/include path for the dependencies (https://cmake.org/Wiki/CMake:How_To_Find_Libraries). // Modify the project CMakeLists.txt and add: list(APPEND CMAKE_MODULE_PATH "PathToDependenciesCmakeModulesGoesHere"). diff --git a/src/Conf.cpp b/src/Conf.cpp index 41cc157..941bdd7 100644 --- a/src/Conf.cpp +++ b/src/Conf.cpp @@ -1,10 +1,17 @@ #include "../include/Conf.hpp" #include "../include/types.hpp" #include "../external/utf8/unchecked.h" +#include <iostream> using namespace std; using u8string = utf8::unchecked::iterator<char*>; +#if OS_FAMILY == OS_FAMILY_POSIX +#define ferr std::cerr +#else +#define ferr std::wcerr +#endif + namespace sibs { static const string EMPTY_STRING = ""; @@ -196,11 +203,11 @@ namespace sibs class Parser { public: - static Result<bool> parse(const char *code, const ConfigCallback &callback) + static Result<bool> parse(const char *code, ConfigCallback &callback) { try { - Parser parser(code, (ConfigCallback*)&callback); + Parser parser(code, &callback); parser.parse(); return Result<bool>::Ok(true); } @@ -438,7 +445,7 @@ namespace sibs bool objectDefined; }; - Result<bool> Config::readFromFile(const _tinydir_char_t *filepath, const ConfigCallback &callback) + Result<bool> Config::readFromFile(const _tinydir_char_t *filepath, ConfigCallback &callback) { Result<StringView> fileContentResult = getFileContent(filepath); if(fileContentResult.isErr()) @@ -463,6 +470,50 @@ namespace sibs } return false; } + + void readSibsConfig(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig, FileString &buildPath) + { + Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); + if(result.isErr()) + { + ferr << "Failed to read config: " << toFileString(result.getErrMsg()) << endl; + exit(6); + } + + if(sibsConfig.getPackageName().empty()) + { + ferr << "project.conf is missing required field package.name" << endl; + 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); + } + + buildPath = projectPath + TINYDIR_STRING("/sibs-build/"); + switch(sibsConfig.getOptimizationLevel()) + { + case OPT_LEV_DEBUG: + buildPath += TINYDIR_STRING("debug"); + break; + case OPT_LEV_RELEASE: + buildPath += TINYDIR_STRING("release"); + break; + } + + if(sibsConfig.shouldBuildTests() && sibsConfig.getTestPath().empty()) + { + printf("Project is missing package.tests config. No tests to build\n"); + exit(0); + } + } const char* asString(Platform platform) { diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp index eee37dd..8618cfd 100644 --- a/src/GlobalLib.cpp +++ b/src/GlobalLib.cpp @@ -1,5 +1,6 @@ #include "../include/GlobalLib.hpp" #include "../include/FileUtil.hpp" +#include "../backend/BackendUtils.hpp" #include "../backend/ninja/Ninja.hpp" #include "../include/Conf.hpp" #include "../include/curl.hpp" @@ -46,26 +47,6 @@ namespace sibs } } } - - const _tinydir_char_t *sourceFileExtensions[] = { TINYDIR_STRING("c"),TINYDIR_STRING("cc"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx") }; - bool isSourceFile(tinydir_file *file) - { - if(!file->is_reg) - return false; - - for(const _tinydir_char_t *sourceFileExtension : sourceFileExtensions) - { - if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0) - return true; - } - - return false; - } - - bool isPathSubPathOf(const _tinydir_char_t *path, const FileString &subPathOf) - { - return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0; - } Result<bool> GlobalLib::getLibs(const std::vector<PackageListDependency*> &libs, const SibsConfig &parentConfig, const FileString &globalLibRootDir, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc, GlobalIncludeDirCallbackFunc globalIncludeDirCallback) { @@ -284,93 +265,7 @@ namespace sibs else { backend::Ninja ninja; - // TODO: Use same source file finder as in main.cpp - 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(pathNative.c_str() + sibsConfig.getProjectPath().size() + 1); - ninja.addSourceFile(fileNameNative.c_str()); - } - else - { - //printf("Ignoring non-source file: %s\n", file->path + projectPath.size()); - } - } - else - { - // 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(pathNative.c_str(), sibsConfig.getTestPath())) - { - string filePathUtf8 = toUtf8(pathNative.c_str()); - ninja.addTestSourceDir(filePathUtf8.c_str()); - } - else if(!directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs())) - walkDir(file->path, collectSourceFiles); - } - }; - walkDir(packageDir.c_str(), collectSourceFiles); - - if (!ninja.getSourceFiles().empty()) - { - string libPath = toUtf8(buildPath); - switch (sibsConfig.getCompiler()) - { - case Compiler::GCC: - { - libPath += "/lib"; - libPath += dependencyName; - if (sibsConfig.getPackageType() == PackageType::STATIC) - { - libPath += ".a"; - string libPathCmd = "'"; - libPathCmd += libPath; - libPathCmd += "'"; - staticLinkerFlagCallbackFunc(libPathCmd); - } - else - { - libPath += ".so"; - string libPathCmd = "'"; - libPathCmd += libPath; - libPathCmd += "'"; - dynamicLinkerFlagCallbackFunc(libPathCmd); - } - break; - } - case Compiler::MSVC: - { - libPath += "/"; - libPath += dependencyName; - if (sibsConfig.getPackageType() == PackageType::STATIC) - { - libPath += ".lib"; - string libPathCmd = "\""; - libPathCmd += libPath; - libPathCmd += "\""; - staticLinkerFlagCallbackFunc(libPathCmd); - } - else - { - libPath += ".lib"; - string libPathCmd = "\""; - libPathCmd += libPath; - libPathCmd += "\""; - dynamicLinkerFlagCallbackFunc(libPathCmd); - } - break; - } - } - } - + backend::BackendUtils::collectSourceFiles(packageDir.c_str(), &ninja, sibsConfig); return ninja.build(sibsConfig, buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallbackFunc, globalIncludeDirCallback); } } diff --git a/src/main.cpp b/src/main.cpp index b9d6c1b..910380a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "../include/Conf.hpp" #include "../include/Exec.hpp" #include "../include/CmakeModule.hpp" +#include "../backend/BackendUtils.hpp" #include "../backend/ninja/Ninja.hpp" using namespace std; @@ -42,11 +43,6 @@ using namespace std::chrono; // Might need to make it possible to define variables if a dependency exists (or doesn't exist) because the code might have // preprocessor like: USE_LIBSODIUM or NO_LIBSODIUM. -// TODO: Set c++ standard to c++11 and c standard to c98 - for consistency across different compilers and compiler version. -// It should be possible to override language version in project.conf - -// TODO: If file extension is common c extension (.c, ...) then remove cast checking (for example using malloc without casting result to result type) - // TODO: When building a sibs project, add a hardlink in ~/.sibs/lib to it. This allows us to have dependency to a project that we can modify // without having to commit & push to remote @@ -199,48 +195,17 @@ bool isPathSubPathOf(const FileString &path, const FileString &subPathOf) return _tinydir_strncmp(path.c_str(), subPathOf.c_str(), subPathOf.size()) == 0; } -int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, const SibsConfig &sibsConfig) +int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig) { - Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); - if(result.isErr()) - { - ferr << "Failed to read config: " << toFileString(result.getErrMsg()) << endl; - exit(6); - } - - if(sibsConfig.getPackageName().empty()) - { - ferr << "project.conf is missing required field package.name" << endl; - 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); - } - - FileString buildPath = projectPath + TINYDIR_STRING("/sibs-build/"); - switch(sibsConfig.getOptimizationLevel()) - { - case OPT_LEV_DEBUG: - buildPath += TINYDIR_STRING("debug"); - break; - case OPT_LEV_RELEASE: - buildPath += TINYDIR_STRING("release"); - break; - } + FileString buildPath; + readSibsConfig(projectPath, projectConfFilePath, sibsConfig, buildPath); auto startTime = high_resolution_clock::now(); if(sibsConfig.shouldUseCmake()) { auto dummyCallback = [](const string&){}; + // TODO: Add test and sub projects CmakeModule cmakeModule; Result<bool> cmakeCompileResult = cmakeModule.compile(sibsConfig, buildPath, dummyCallback, dummyCallback, dummyCallback); if(!cmakeCompileResult) @@ -252,42 +217,36 @@ int buildProject(const FileString &projectPath, const FileString &projectConfFil else { backend::Ninja ninja; - FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file) + // TODO: Do same for cmake + switch (sibsConfig.getOptimizationLevel()) { - FileString pathNative = file->path; - #if OS_FAMILY == OS_FAMILY_WINDOWS - replaceChar(pathNative, L'/', L'\\'); - #endif - if(file->is_reg) + case OPT_LEV_DEBUG: { - if (isSourceFile(file)) + // 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 filePathUtf8 = toUtf8(pathNative.c_str() + sibsConfig.getProjectPath().size()); - ninja.addSourceFile(filePathUtf8.c_str()); - } - else - { - //printf("Ignoring non-source file: %s\n", file->path + projectPath.size()); + string staticLibCmd = "\""; + staticLibCmd += staticLib; + staticLibCmd += "\""; + ninja.addDependency(staticLibCmd); } + break; } - else + case OPT_LEV_RELEASE: { - if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(pathNative.c_str(), sibsConfig.getTestPath())) + // 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 filePathUtf8 = toUtf8(pathNative.c_str()); - ninja.addTestSourceDir(filePathUtf8.c_str()); + string staticLibCmd = "\""; + staticLibCmd += staticLib; + staticLibCmd += "\""; + ninja.addDependency(staticLibCmd); } - else if(!directoryToIgnore(pathNative, sibsConfig.getIgnoreDirs())) - walkDir(file->path, collectSourceFiles); + break; } - }; - walkDir(projectPath.c_str(), collectSourceFiles); - - if(sibsConfig.shouldBuildTests() && sibsConfig.getTestPath().empty()) - { - printf("Project is missing package.tests config. No tests to build\n"); - exit(0); } + + backend::BackendUtils::collectSourceFiles(projectPath.c_str(), &ninja, sibsConfig); Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str()); if(buildFileResult.isErr()) |