aboutsummaryrefslogtreecommitdiff
path: root/backend/ninja
diff options
context:
space:
mode:
Diffstat (limited to 'backend/ninja')
-rw-r--r--backend/ninja/Ninja.cpp75
-rw-r--r--backend/ninja/Ninja.hpp5
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;
};
}