diff options
Diffstat (limited to 'backend/ninja')
-rw-r--r-- | backend/ninja/Ninja.cpp | 75 | ||||
-rw-r--r-- | backend/ninja/Ninja.hpp | 5 |
2 files changed, 65 insertions, 15 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index b2a073b..49bda4f 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -42,7 +42,29 @@ namespace backend ++i; } - return move(result); + return result; + } + + bool endsWith(const string &str, const string &endWithStr) + { + if(endWithStr.size() > str.size()) + return false; + else + return strncmp(&str[str.size() - endWithStr.size()], &endWithStr[0], endWithStr.size()) == 0; + } + + Ninja::LibraryType getNinjaLibraryType(PackageType packageType) + { + switch(packageType) + { + case PackageType::EXECUTABLE: + return Ninja::LibraryType::EXECUTABLE; + case PackageType::STATIC: + return Ninja::LibraryType::STATIC; + case PackageType::DYNAMIC: + case PackageType::LIBRARY: + return Ninja::LibraryType::DYNAMIC; + } } string getIncludeOptionFlag(Compiler compiler, const string &filepath) @@ -117,8 +139,7 @@ namespace backend } } - Ninja::Ninja(LibraryType _libraryType) : - libraryType(_libraryType) + Ninja::Ninja() { } @@ -183,7 +204,7 @@ namespace backend } return false; } - + #if OS_FAMILY == OS_FAMILY_POSIX Result<bool> validatePkgConfigPackageVersionExists(const Dependency &dependency) { @@ -299,6 +320,8 @@ namespace backend if(createBuildDirResult.isErr()) return createBuildDirResult; + LibraryType libraryType = getNinjaLibraryType(config.getPackageType()); + string savePathUtf8 = toUtf8(savePath); FileString ninjaBuildFilePath = savePath; @@ -325,6 +348,19 @@ namespace backend } result += "\n\n"; + string defines; + for(const auto &definePair : config.getDefines()) + { + defines += " '-D"; + defines += definePair.first; + defines += "="; + defines += definePair.second; + defines += "'"; + } + + if(!defines.empty()) + printf("Custom define: %s\n", defines.c_str()); + string compilerName; switch (config.getCompiler()) { @@ -431,6 +467,9 @@ namespace backend objectNames.reserve(sourceFiles.size()); for(const string &sourceFile : sourceFiles) { + string sourceFileLanguage = "c++"; + if(endsWith(sourceFile, ".c")) + sourceFileLanguage = "c"; //string sourceFileEncoded = sourceFile; //replace(sourceFileEncoded, '/', '@'); string objectName = config.getPackageName() + "@exe/" + sourceFile; @@ -440,7 +479,9 @@ namespace backend result += ": cpp_COMPILER ../../"; result += sourceFile; result += "\n"; - result += " ARGS = $globalIncDir"; + result += " ARGS = $globalIncDir "; + if(!defines.empty()) + result += defines; if(config.getCompiler() != Compiler::MSVC) result += " '-I" + config.getPackageName() + "@exe' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' " + optimizationFlags + " '-g'"; result += "\n\n"; @@ -508,7 +549,7 @@ namespace backend break; } } - + if(!allLinkerFlags.empty()) { result += allLinkerFlags; @@ -592,7 +633,7 @@ namespace backend if(!buildResult) return buildResult; - Result<bool> buildTestResult = buildTests(config, projectGeneratedBinary); + Result<bool> buildTestResult = buildTests(projectGeneratedBinary, config, savePath); if(!buildTestResult) return buildTestResult; @@ -614,14 +655,24 @@ namespace backend return false; } - Result<bool> Ninja::buildTests(const SibsConfig &parentConfig, const std::string &projectGeneratedBinary) + Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary, const SibsConfig &config, const char *savePath) { if(testSourceDirs.empty()) return Result<bool>::Ok(true); - // TODO: Include executable as dependency??? or compile project as dynamic library even if it's not a library - if(libraryType == LibraryType::EXECUTABLE) - return Result<bool>::Err("Unit tests are currently only supported in projects that compile to static/dynamic library"); + // Tests need parent project as dependency. Executables can't be included as dependency so we build it as dynamic library. + // `build` also builds tests + if(getNinjaLibraryType(config.getPackageType()) == LibraryType::EXECUTABLE) + { + SibsConfig parentProjConfigLib = config; + parentProjConfigLib.setPackageType(PackageType::DYNAMIC); + // HACK: We can build a package that is defined as executable and contains main function by redefining `main` + // as something else. + // TODO: Do not allow defining `main` in project.conf or as program argument to sibs (when sibs supports defines). + // It's ok if `define` fails. It could fail if `main` has already been replaced by other tests somehow. + parentProjConfigLib.define("main", "sibs_lib_ignore_main"); + return build(parentProjConfigLib, savePath, nullptr, nullptr); + } for(const string &testSourceDir : testSourceDirs) { @@ -635,7 +686,7 @@ namespace backend projectConfFilePath += TINYDIR_STRING("/project.conf"); FileType projectConfFileType = getFileType(projectConfFilePath.c_str()); - SibsTestConfig sibsTestConfig(parentConfig.getCompiler(), testSourceDirNative); + SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative); if(projectConfFileType == FileType::REGULAR) { Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig); diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp index e37a5ca..36a57ff 100644 --- a/backend/ninja/Ninja.hpp +++ b/backend/ninja/Ninja.hpp @@ -22,7 +22,7 @@ namespace backend DYNAMIC, }; - Ninja(LibraryType libraryType = LibraryType::EXECUTABLE); + Ninja(); void addSourceFile(const char *filepath); void addTestSourceDir(const char *dir); @@ -30,7 +30,7 @@ namespace backend const std::vector<std::string>& getSourceFiles() const; sibs::Result<bool> build(const sibs::SibsConfig &config, const _tinydir_char_t *savePath, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc = nullptr, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback = nullptr); private: - sibs::Result<bool> buildTests(const sibs::SibsConfig &parentConfig, const std::string &projectGeneratedBinary); + sibs::Result<bool> buildTests(const std::string &projectGeneratedBinary, const sibs::SibsConfig &config, const char *savePath); bool containsSourceFile(const std::string &filepath) const; bool containsTestSourceDir(const std::string &dir) const; bool containsDependency(const std::string &dependency) const; @@ -40,7 +40,6 @@ namespace backend std::vector<std::string> sourceFiles; std::vector<std::string> testSourceDirs; std::vector<std::string> binaryDependencies; - LibraryType libraryType; }; } |