From 23117906c571714b0b55caf35cf9f876d1f9fa2e Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 21 Mar 2018 14:56:51 +0100 Subject: 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 --- src/CmakeModule.cpp | 13 ++++--- src/Conf.cpp | 57 +++++++++++++++++++++++++-- src/GlobalLib.cpp | 109 +--------------------------------------------------- src/main.cpp | 91 ++++++++++++------------------------------- 4 files changed, 89 insertions(+), 181 deletions(-) (limited to 'src') 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 using namespace std; using u8string = utf8::unchecked::iterator; +#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 parse(const char *code, const ConfigCallback &callback) + static Result parse(const char *code, ConfigCallback &callback) { try { - Parser parser(code, (ConfigCallback*)&callback); + Parser parser(code, &callback); parser.parse(); return Result::Ok(true); } @@ -438,7 +445,7 @@ namespace sibs bool objectDefined; }; - Result Config::readFromFile(const _tinydir_char_t *filepath, const ConfigCallback &callback) + Result Config::readFromFile(const _tinydir_char_t *filepath, ConfigCallback &callback) { Result 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 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 GlobalLib::getLibs(const std::vector &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 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 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 buildFileResult = ninja.build(sibsConfig, buildPath.c_str()); if(buildFileResult.isErr()) -- cgit v1.2.3