aboutsummaryrefslogtreecommitdiff
path: root/backend/ninja/Ninja.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backend/ninja/Ninja.cpp')
-rw-r--r--backend/ninja/Ninja.cpp88
1 files changed, 59 insertions, 29 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index fb081de..614d08c 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -1,4 +1,5 @@
#include <cstring>
+#include "../BackendUtils.hpp"
#include "Ninja.hpp"
#include "../../include/FileUtil.hpp"
#include "../../include/Exec.hpp"
@@ -237,6 +238,11 @@ namespace backend
if(!containsDependency(binaryFile))
binaryDependencies.emplace_back(binaryFile);
}
+
+ void Ninja::addSubProject(Ninja *subProject, SibsConfig *config, sibs::FileString &&buildPath)
+ {
+ subProjects.emplace_back(NinjaSubProject{ subProject, config, move(buildPath) });
+ }
const std::vector<std::string>& Ninja::getSourceFiles() const
{
@@ -318,7 +324,7 @@ namespace backend
else
{
const PkgConfigFlags &pkgConfigFlag = pkgConfigFlagsResult.unwrap();
- if (dynamicLinkerFlagCallback && !pkgConfigFlag.linkerFlags.empty())
+ if (!pkgConfigFlag.linkerFlags.empty())
dynamicLinkerFlagCallback(pkgConfigFlag.linkerFlags);
if(!pkgConfigFlag.cflags.empty())
cflagsCallbackFunc(pkgConfigFlag.cflags);
@@ -338,6 +344,26 @@ namespace backend
C,
CPP
};
+
+ Result<bool> Ninja::buildSubProjects(LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
+ {
+ for(auto &subProject : subProjects)
+ {
+ if(subProject.config->getPackageType() == PackageType::EXECUTABLE)
+ {
+ string errMsg = "The sub project ";
+ errMsg += toUtf8(subProject.buildPath);
+ errMsg += " is an executable. Only libraries can be sub projects";
+ return Result<bool>::Err(errMsg);
+ }
+
+ Result<bool> buildResult = subProject.subProject->build(*subProject.config, subProject.buildPath.c_str(), staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
+ if(!buildResult)
+ return buildResult;
+ }
+
+ return Result<bool>::Ok(true);
+ }
Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
@@ -405,7 +431,7 @@ namespace backend
#endif
// TODO: Somehow check loading order, because it has to be correct to work.. Or does it for dynamic libraries?
- // Anyways it's required for static libraries (especially on Windows)
+ // Anyways it's required for static libraries
for (const string &binaryDependency : binaryDependencies)
{
allLinkerFlags += " ";
@@ -413,6 +439,7 @@ namespace backend
}
string staticLinkerFlags;
+ auto parentProjStaticLinkerFlagCallbackFunc = staticLinkerFlagCallbackFunc;
if (!staticLinkerFlagCallbackFunc || libraryType == LibraryType::DYNAMIC)
{
staticLinkerFlagCallbackFunc = [&staticLinkerFlags](const string &linkerFlag)
@@ -423,8 +450,8 @@ namespace backend
}
string dynamicLinkerFlags;
- // TODO: Do same for cmake
- if (!sourceFiles.empty())
+ auto parentProjDynamicLinkerFlagCallbackFunc = dynamicLinkerFlagCallback;
+ if(!dynamicLinkerFlagCallback || libraryType != LibraryType::STATIC)
{
dynamicLinkerFlagCallback = [&dynamicLinkerFlags](const string &linkerFlag)
{
@@ -439,6 +466,10 @@ namespace backend
cflags += " ";
cflags += dependencyCflags;
};
+
+ Result<bool> buildSubProjectResult = buildSubProjects(staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
+ if(!buildSubProjectResult)
+ return buildSubProjectResult;
Result<bool> linkerFlags = getLinkerFlags(config, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback, cflagsCallbackFunc);
if (linkerFlags.isErr())
@@ -739,13 +770,13 @@ namespace backend
objectNames.emplace_back(objectName);
}
- string projectGeneratedBinary;
+ string projectGeneratedBinaryFlags;
if (!sourceFiles.empty())
{
- projectGeneratedBinary = allLinkerFlags;
- projectGeneratedBinary += " \"";
+ string projectGeneratedBinary = "\"";
projectGeneratedBinary += savePathUtf8;
projectGeneratedBinary += "/";
+
switch (libraryType)
{
case LibraryType::EXECUTABLE:
@@ -776,7 +807,11 @@ namespace backend
result += allLinkerFlags;
}
result += "\n\n";
+
projectGeneratedBinary += config.getPackageName();
+ #if OS_FAMILY == OS_FAMILY_WINDOWS
+ projectGeneratedBinary += ".exe";
+ #endif
break;
}
case LibraryType::STATIC:
@@ -804,6 +839,11 @@ namespace backend
break;
}
}
+
+ projectGeneratedBinary += "\"";
+ if(parentProjStaticLinkerFlagCallbackFunc)
+ parentProjStaticLinkerFlagCallbackFunc(projectGeneratedBinary);
+
break;
}
case LibraryType::DYNAMIC:
@@ -841,13 +881,19 @@ namespace backend
//result += " '-Wl,--no-whole-archive'";
}
result += "\n\n";
+
+ projectGeneratedBinary += "\"";
+ if(parentProjDynamicLinkerFlagCallbackFunc)
+ parentProjDynamicLinkerFlagCallbackFunc(projectGeneratedBinary);
+
break;
}
default:
assert(false);
return Result<bool>::Err("Unexpected error");
}
- projectGeneratedBinary += "\"";
+
+ projectGeneratedBinaryFlags = allLinkerFlags + " " + projectGeneratedBinary;
Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size()));
if (fileOverwriteResult.isErr())
@@ -863,30 +909,14 @@ namespace backend
// TODO: If tests are being run (sibs test) and root project is an executable, do not run compile (above code) as executable.
// Sibs test will compile root project as dynamic library so you end up compiling the project twice, first as an executable and then as a dynamic library.
// Even if the root project has been built before and there is cached object, it will take a few seconds to run compile
- Result<bool> buildTestResult = buildTests(projectGeneratedBinary, config, savePath, dependencyExportIncludeDirs);
+ Result<bool> buildTestResult = buildTests(projectGeneratedBinaryFlags, config, savePath, dependencyExportIncludeDirs);
if(!buildTestResult)
return buildTestResult;
return Result<bool>::Ok(true);
}
- // TODO: Add "c++" file extension, seems to be used in some places?
- 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;
- }
-
- Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary, const SibsConfig &config, const _tinydir_char_t *savePath, const string &parentDependencyExportIncludeDirs)
+ Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinaryFlags, const SibsConfig &config, const _tinydir_char_t *savePath, const string &parentDependencyExportIncludeDirs)
{
if(testSourceDirs.empty() || !config.shouldBuildTests())
return Result<bool>::Ok(true);
@@ -940,12 +970,12 @@ namespace backend
backend::Ninja ninja;
ninja.addGlobalIncludeDirs(parentExportIncludeDirs);
- if(!projectGeneratedBinary.empty())
- ninja.addDependency(projectGeneratedBinary);
+ if(!projectGeneratedBinaryFlags.empty())
+ ninja.addDependency(projectGeneratedBinaryFlags);
// TODO: Use same source file finder as in main.cpp
walkDirFilesRecursive(testSourceDirNative.c_str(), [&ninja, &sibsTestConfig](tinydir_file *file)
{
- if (isSourceFile(file))
+ if (backend::BackendUtils::isSourceFile(file))
{
string filePathUtf8 = toUtf8(file->path + sibsTestConfig.getProjectPath().size() + 1);
ninja.addSourceFile(filePathUtf8.c_str());