aboutsummaryrefslogtreecommitdiff
path: root/backend/ninja
diff options
context:
space:
mode:
Diffstat (limited to 'backend/ninja')
-rw-r--r--backend/ninja/Ninja.cpp223
1 files changed, 79 insertions, 144 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index ea3d96f..be78ba1 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -40,43 +40,6 @@ namespace backend
return result;
}
- static string join(const vector<string> &list, const char *joinStr)
- {
- if(list.empty()) return "";
- string result;
- long stringSize = 0;
- long joinStrLen = strlen(joinStr);
- int i = 0;
- for(const string &str : list)
- {
- stringSize += str.size();
- if(!str.empty() && i > 0)
- stringSize += joinStrLen;
- ++i;
- }
-
- result.reserve(stringSize);
-
- i = 0;
- for(const string &str : list)
- {
- if(i > 0)
- result += joinStr;
- result += str;
- ++i;
- }
-
- return result;
- }
-
- static 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;
- }
-
static Ninja::LibraryType getNinjaLibraryType(PackageType packageType)
{
switch(packageType)
@@ -147,31 +110,6 @@ namespace backend
return "";
}
- static string getObjectFileNameFlag(Compiler compiler, const string &objectFileName)
- {
- string result;
- switch (compiler)
- {
- case Compiler::MINGW_W64:
- case Compiler::GCC:
- {
- result = "-o ";
- result += objectFileName;
- break;
- }
- case Compiler::MSVC:
- {
- result = "/Fo";
- result += objectFileName;
- break;
- }
- default:
- assert(false);
- break;
- }
- return result;
- }
-
static vector<ninja::NinjaArg> getLanguageVersionFlag(Compiler compiler, CVersion cVersion)
{
switch (compiler)
@@ -320,22 +258,20 @@ namespace backend
Result<bool> Ninja::getLinkerFlags(const SibsConfig &config, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback, CflagsCallbackFunc cflagsCallbackFunc) const
{
- const vector<PackageListDependency*> &packageListDependencies = config.getPackageListDependencies();
+ const vector<PackageListDependency> &packageListDependencies = config.getPackageListDependencies();
Result<FileString> globalLibDirResult = getHomeDir();
if (!globalLibDirResult)
return Result<bool>::Err(globalLibDirResult);
- FileString globalLibDir = globalLibDirResult.unwrap();
- globalLibDir += TINYDIR_STRING("/.cache/sibs/lib/");
- globalLibDir += toFileString(asString(config.platform));
- Result<bool> createGlobalLibDirResult = createDirectoryRecursive(globalLibDir.c_str());
+ Path globalLibDir = Path(globalLibDirResult.unwrap()).join(".cache/sibs/lib").join(toFileString(asString(config.platform)));
+ Result<bool> createGlobalLibDirResult = createDirectoryRecursive(globalLibDir.data.c_str());
if(createGlobalLibDirResult.isErr())
return createGlobalLibDirResult;
// If pkg-config is not available then it will be ignored and we check if package instead exists as a global lib (on github etc)
- vector<PackageListDependency*> globalLibDependencies;
- vector<PackageListDependency*> pkgConfigDependencies;
- for(PackageListDependency *dependency : packageListDependencies)
+ vector<PackageListDependency> globalLibDependencies;
+ vector<PackageListDependency> pkgConfigDependencies;
+ for(const PackageListDependency &dependency : packageListDependencies)
{
// PkgConfig libraries, even the static ones are most likely not built statically against libgcc/libc++, so we don't use them
if(!config.packaging && PkgConfig::validatePkgConfigPackageVersionExists(dependency))
@@ -353,7 +289,7 @@ namespace backend
{
printf("%s, using global lib...\n", pkgConfigFlagsResult.getErrMsg().c_str());
globalLibDependencies.reserve(globalLibDependencies.size() + pkgConfigDependencies.size());
- for (PackageListDependency *pkgConfigDependency : pkgConfigDependencies)
+ for (const PackageListDependency &pkgConfigDependency : pkgConfigDependencies)
{
globalLibDependencies.push_back(pkgConfigDependency);
}
@@ -368,7 +304,7 @@ namespace backend
cflagsCallbackFunc(pkgConfigFlag.cflags);
}
- return GlobalLib::getLibs(globalLibDependencies, config, globalLibDir, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
+ return GlobalLib::getLibs(globalLibDependencies, config, globalLibDir.data, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
}
Result<bool> Ninja::buildSubProjects(LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
@@ -764,9 +700,9 @@ namespace backend
Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
- string cCompilerName = BackendUtils::getCompilerCExecutable(config.getCompiler());
- string cppCompilerName = BackendUtils::getCompilerCppExecutable(config.getCompiler());
- string compilerLinker = BackendUtils::getCompilerLinker(config.getCompiler());
+ std::vector<FileString> cCompilerName = BackendUtils::getCompilerCExecutable(config.getCompiler());
+ std::vector<FileString> cppCompilerName = BackendUtils::getCompilerCppExecutable(config.getCompiler());
+ std::vector<FileString> compilerLinker = BackendUtils::getCompilerLinker(config.getCompiler());
RuntimeCompilerType cCompilerType = BackendUtils::getCCompilerType(config.getCompiler());
RuntimeCompilerType cppCompilerType = BackendUtils::getCppCompilerType(config.getCompiler());
@@ -786,19 +722,17 @@ namespace backend
if (!createBuildDirResult)
return createBuildDirResult;
- FileString generatedHeadersDir = config.getProjectPath() + TINYDIR_STRING("/sibs-build/");
- generatedHeadersDir += toFileString(asString(config.platform)) + TINYDIR_STRING("/");
- generatedHeadersDir += TINYDIR_STRING("generated-headers");
- Result<bool> createGeneratedHeadersDirResult = createDirectoryRecursive(generatedHeadersDir.c_str());
+ Path generatedHeadersDir = Path(config.getProjectPath()).join(TINYDIR_STRING("sibs-build")).join(toFileString(asString(config.platform))).join(TINYDIR_STRING("generated-headers"));
+ Result<bool> createGeneratedHeadersDirResult = createDirectoryRecursive(generatedHeadersDir.data.c_str());
if (!createGeneratedHeadersDirResult)
return createGeneratedHeadersDirResult;
- FileString generatedZigHeadersDir = generatedHeadersDir + TINYDIR_STRING("/zig");
- Result<bool> createGeneratedZigHeadersDirResult = createDirectory(generatedZigHeadersDir.c_str());
+ Path generatedZigHeadersDir = Path(generatedHeadersDir).join(TINYDIR_STRING("zig"));
+ Result<bool> createGeneratedZigHeadersDirResult = createDirectory(generatedZigHeadersDir.data.c_str());
if (!createGeneratedZigHeadersDirResult)
return createGeneratedZigHeadersDirResult;
- string generatedZigHeaderDirUtf8 = toUtf8(generatedZigHeadersDir);
+ string generatedZigHeaderDirUtf8 = toUtf8(generatedZigHeadersDir.data);
LibraryType libraryType = getNinjaLibraryType(config.getPackageType());
// TODO: Instead of statically linking everything, maybe we should build everything as they prefer to be built
@@ -814,8 +748,7 @@ namespace backend
string savePathUtf8 = toUtf8(savePath);
string projectPathUtf8 = toUtf8(config.getProjectPath());
- FileString ninjaBuildFilePath = savePath;
- ninjaBuildFilePath += TINYDIR_STRING("/build.ninja");
+ Path ninjaBuildFilePath = Path(savePath).join(TINYDIR_STRING("build.ninja"));
ninja::NinjaBuildFile ninjaBuildFile;
@@ -929,7 +862,7 @@ namespace backend
}
globalIncDir += dependencyExportIncludeDirs;
- globalIncDir += " " + getIncludeOptionFlag(config.getCompiler(), toUtf8(generatedHeadersDir));
+ globalIncDir += " " + getIncludeOptionFlag(config.getCompiler(), toUtf8(generatedHeadersDir.data));
ninjaBuildFile.defineGlobalVariable("globalIncDir", globalIncDir);
// TODO: Find a better way to convert includes, this could be slow...
ninjaBuildFile.defineGlobalVariable("globalIncDirZig", convertCIncludeSyntaxToZigInclude(config.getCompiler(), globalIncDir));
@@ -992,7 +925,6 @@ namespace backend
case LibraryType::EXECUTABLE:
{
baseCompileCArgs.insert(baseCompileCArgs.end(), {
- ninja::NinjaArg::createRaw(cCompilerName),
ninja::NinjaArg("-c"),
ninja::NinjaArg::createRaw("-fPIE -fPIC"),
ninja::NinjaArg("$in"),
@@ -1005,7 +937,6 @@ namespace backend
case LibraryType::DYNAMIC:
{
baseCompileCArgs.insert(baseCompileCArgs.end(), {
- ninja::NinjaArg::createRaw(cCompilerName),
ninja::NinjaArg("-c"),
ninja::NinjaArg("-fPIC"),
ninja::NinjaArg("$in"),
@@ -1064,11 +995,18 @@ namespace backend
compileCCommand.push_back(std::move(sanitizerFlag));
compileCppCommand = compileCCommand;
- compileCppCommand[0] = ninja::NinjaArg::createRaw(cppCompilerName);
compileCppCommand.insert(compileCppCommand.end(), {
ninja::NinjaArg("-fexceptions"),
ninja::NinjaArg("-Wnon-virtual-dtor")
});
+
+ for(auto it = cCompilerName.rbegin(), end = cCompilerName.rend(); it != end; ++it) {
+ compileCCommand.insert(compileCCommand.begin(), ninja::NinjaArg(*it));
+ }
+
+ for(auto it = cppCompilerName.rbegin(), end = cppCompilerName.rend(); it != end; ++it) {
+ compileCppCommand.insert(compileCppCommand.begin(), ninja::NinjaArg(*it));
+ }
break;
}
case Compiler::MSVC:
@@ -1388,9 +1326,17 @@ namespace backend
case Compiler::MINGW_W64:
case Compiler::GCC:
{
+ if(usesCppFiles) {
+ for(const FileString &arg : cppCompilerName) {
+ buildExeArgs.push_back(ninja::NinjaArg(arg));
+ }
+ } else {
+ for(const FileString &arg : cCompilerName) {
+ buildExeArgs.push_back(ninja::NinjaArg(arg));
+ }
+ }
string rpath = extractDynamicLibDirsFromLinkerFlags(dynamicLinkerFlags);
buildExeArgs.insert(buildExeArgs.end(), {
- ninja::NinjaArg::createRaw(usesCppFiles ? cppCompilerName : cCompilerName),
ninja::NinjaArg::createRaw("-o"),
ninja::NinjaArg::createRaw("$out"),
ninja::NinjaArg::createRaw("$in"),
@@ -1437,9 +1383,11 @@ namespace backend
}
case Compiler::MSVC:
{
+ for(const FileString &arg : cppCompilerName) {
+ buildExeArgs.push_back(ninja::NinjaArg(arg));
+ }
// TODO: Do not link all of these. Find a way to only link the ones that are needed
buildExeArgs.insert(buildExeArgs.end(), {
- ninja::NinjaArg::createRaw(cppCompilerName),
ninja::NinjaArg::createRaw("$in"),
ninja::NinjaArg::createRaw("/Fe$out"),
ninja::NinjaArg::createRaw("Ws2_32.lib"),
@@ -1535,8 +1483,10 @@ namespace backend
case Compiler::MINGW_W64:
case Compiler::GCC:
{
+ for(const FileString &arg : compilerLinker) {
+ buildStaticArgs.push_back(ninja::NinjaArg(arg));
+ }
buildStaticArgs.insert(buildStaticArgs.end(), {
- ninja::NinjaArg::createRaw(compilerLinker),
ninja::NinjaArg::createRaw("rcs"),
ninja::NinjaArg::createRaw("$out"),
ninja::NinjaArg::createRaw("$in")
@@ -1545,8 +1495,10 @@ namespace backend
}
case Compiler::MSVC:
{
+ for(const FileString &arg : compilerLinker) {
+ buildStaticArgs.push_back(ninja::NinjaArg(arg));
+ }
buildStaticArgs.insert(buildStaticArgs.end(), {
- ninja::NinjaArg::createRaw(compilerLinker),
ninja::NinjaArg::createRaw("/OUT:$out"),
ninja::NinjaArg::createRaw("$in")
});
@@ -1623,8 +1575,16 @@ namespace backend
case Compiler::MINGW_W64:
case Compiler::GCC:
{
+ if(usesCppFiles) {
+ for(const FileString &arg : cppCompilerName) {
+ buildDynamicArgs.push_back(ninja::NinjaArg(arg));
+ }
+ } else {
+ for(const FileString &arg : cCompilerName) {
+ buildDynamicArgs.push_back(ninja::NinjaArg(arg));
+ }
+ }
buildDynamicArgs.insert(buildDynamicArgs.end(), {
- ninja::NinjaArg::createRaw(usesCppFiles ? cppCompilerName : cCompilerName),
ninja::NinjaArg::createRaw("$in"),
ninja::NinjaArg::createRaw("-shared"),
ninja::NinjaArg("-Wl,-soname," + generatedFile),
@@ -1665,8 +1625,10 @@ namespace backend
}
case Compiler::MSVC:
{
+ for(const FileString &arg : compilerLinker) {
+ buildDynamicArgs.push_back(ninja::NinjaArg(arg));
+ }
buildDynamicArgs.insert(buildDynamicArgs.end(), {
- ninja::NinjaArg::createRaw(compilerLinker),
ninja::NinjaArg::createRaw("/OUT:$out"),
ninja::NinjaArg::createRaw("$in"),
ninja::NinjaArg::createRaw("Ws2_32.lib"),
@@ -1735,7 +1697,7 @@ namespace backend
if(!sourceFiles.empty())
{
string result = ninjaBuildFile.generate();
- Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.c_str(), sibs::StringView(result.data(), result.size()));
+ Result<bool> fileOverwriteResult = sibs::fileOverwrite(ninjaBuildFilePath.data.c_str(), sibs::StringView(result.data(), result.size()));
if (fileOverwriteResult.isErr())
return fileOverwriteResult;
@@ -1777,24 +1739,18 @@ namespace backend
parentExportIncludeDirs += getIncludeOptionFlag(config.getCompiler(), parentExportIncludeDir);
}
-#if OS_FAMILY == OS_FAMILY_POSIX
- FileString testSourceDirNative = testSourceDir;
- FileString projectConfFilePath = testSourceDir;
-#else
- FileString testSourceDirNative = utf8To16(testSourceDir);
- FileString projectConfFilePath = testSourceDirNative;
-#endif
- projectConfFilePath += TINYDIR_STRING("/project.conf");
+ Path testSourceDirNative = toFileString(testSourceDir);
+ Path projectConfFilePath = Path(testSourceDirNative).join("project.conf");
- FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
- SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative, config.getOptimizationLevel());
+ FileType projectConfFileType = getFileType(projectConfFilePath.data.c_str());
+ SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative.data, config.getOptimizationLevel());
sibsTestConfig.platform = config.platform;
sibsTestConfig.setSanitize(config.getSanitize());
sibsTestConfig.zigTestFiles = move(config.zigTestFiles);
sibsTestConfig.zigTestAllFiles = config.zigTestAllFiles;
if(projectConfFileType == FileType::REGULAR)
{
- Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig);
+ Result<bool> result = Config::readFromFile(projectConfFilePath.data.c_str(), sibsTestConfig);
if(!result)
return result;
}
@@ -1826,7 +1782,7 @@ namespace backend
bool zigTest = false;
if(config.zigTestAllFiles)
{
- backend::BackendUtils::collectSourceFiles(testSourceDirNative.c_str(), &ninja, sibsTestConfig);
+ backend::BackendUtils::collectSourceFiles(testSourceDirNative.data.c_str(), &ninja, sibsTestConfig);
// TODO: This can be optimized as well. No need to insert non-zig files if we are going to remove them.
// Maybe pass a filter callback function to @collectSourceFiles.
for(auto it = ninja.sourceFiles.begin(); it != ninja.sourceFiles.end(); )
@@ -1853,33 +1809,29 @@ namespace backend
}
else
{
- backend::BackendUtils::collectSourceFiles(testSourceDirNative.c_str(), &ninja, sibsTestConfig);
+ backend::BackendUtils::collectSourceFiles(testSourceDirNative.data.c_str(), &ninja, sibsTestConfig);
}
if(!ninja.getSourceFiles().empty())
{
- FileString buildPath = testSourceDirNative;
- buildPath += TINYDIR_STRING("/sibs-build/") + toFileString(asString(config.platform));
+ Path buildPath = Path(testSourceDirNative).join(TINYDIR_STRING("sibs-build")).join(toFileString(asString(config.platform)));
switch(sibsTestConfig.getOptimizationLevel())
{
case OPT_LEV_DEBUG:
- buildPath += TINYDIR_STRING("/debug");
+ buildPath.join(TINYDIR_STRING("debug"));
break;
case OPT_LEV_RELEASE:
- buildPath += TINYDIR_STRING("/release");
+ buildPath.join(TINYDIR_STRING("release"));
break;
}
- Result<bool> buildFileResult = ninja.build(sibsTestConfig, buildPath.c_str());
+ Result<bool> buildFileResult = ninja.build(sibsTestConfig, buildPath.data.c_str());
if (!buildFileResult)
return buildFileResult;
if(!zigTest)
{
- FileString testExecutableName = buildPath;
- testExecutableName += TINYDIR_STRING("/");
- testExecutableName += toFileString(sibsTestConfig.getPackageName());
- Result<ExecResult> runTestResult = exec(testExecutableName.c_str(), true);
+ Result<ExecResult> runTestResult = exec({ Path(buildPath).join(toFileString(sibsTestConfig.getPackageName())).data }, true);
if(!runTestResult)
return Result<bool>::Err(runTestResult);
@@ -1893,26 +1845,7 @@ namespace backend
Result<bool> Ninja::compile(const _tinydir_char_t *buildFilePath)
{
-#if OS_TYPE == OS_TYPE_LINUX
- FileString command;
- if(isatty(STDOUT_FILENO) == 1)
- {
- command = TINYDIR_STRING("script -eqc 'ninja -C \"");
- command += buildFilePath;
- command += TINYDIR_STRING("\"' /dev/null");
- }
- else
- {
- command = TINYDIR_STRING("ninja -C \"");
- command += buildFilePath;
- command += TINYDIR_STRING("\"");
- }
-#else
- FileString command = TINYDIR_STRING("ninja -C \"");
- command += buildFilePath;
- command += TINYDIR_STRING("\"");
-#endif
- Result<ExecResult> execResult = exec(command.c_str(), true);
+ Result<ExecResult> execResult = exec({ TINYDIR_STRING("ninja"), TINYDIR_STRING("-C"), buildFilePath }, true);
if(execResult.isOk())
{
if(execResult.unwrap().exitCode == 0)
@@ -1929,15 +1862,17 @@ namespace backend
Result<bool> Ninja::buildCompilationDatabase(const _tinydir_char_t *buildFilePath, const FileString &saveDir)
{
- FileString command = TINYDIR_STRING("ninja -C \"");
- command += buildFilePath;
- command += TINYDIR_STRING("\" -t compdb compile_c compile_cpp > \"");
- command += saveDir;
- command += TINYDIR_STRING("/compile_commands.json\"");
- Result<ExecResult> execResult = exec(command.c_str(), false);
+ Result<ExecResult> execResult = exec({
+ TINYDIR_STRING("ninja"), TINYDIR_STRING("-C"), buildFilePath, TINYDIR_STRING("-t"),
+ TINYDIR_STRING("compdb"), TINYDIR_STRING("compile_c"), TINYDIR_STRING("compile_cpp")
+ }, false);
if(execResult)
{
- if(execResult.unwrap().exitCode != 0)
+ if(execResult.unwrap().exitCode == 0)
+ {
+ fileOverwrite(Path(saveDir).join("compile_commands.json").data.c_str(), { execResult.unwrap().execStdout.data(), execResult.unwrap().execStdout.size() });
+ }
+ else
{
string errMsg = "Failed to build compilation database, reason: ";
errMsg += execResult.unwrap().execStdout;