aboutsummaryrefslogtreecommitdiff
path: root/backend/ninja
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-10-30 13:35:36 +0100
committerdec05eba <dec05eba@protonmail.com>2020-07-06 07:39:33 +0200
commit31899d0a48108515d13508b660fb3bb82b869430 (patch)
tree38bae83a3d5dc919e89906ce43571eaf2a210d5f /backend/ninja
parentfa358bcce18c4c6b343eb2a82475d76a6638096a (diff)
Add support for emscripten, fix compdb for tests
Diffstat (limited to 'backend/ninja')
-rw-r--r--backend/ninja/Ninja.cpp125
1 files changed, 89 insertions, 36 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 6aad314..71e9c08 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -390,10 +390,9 @@ namespace backend
static vector<ninja::NinjaArg> getCompilerSanitizerFlags(const SibsConfig &config)
{
- if(config.getCompiler() == Compiler::GCC && config.getSanitize())
+ if(config.getCompiler() == Compiler::GCC || config.getCompiler() == Compiler::MINGW_W64)
{
return {
- ninja::NinjaArg::createRaw("-fno-omit-frame-pointer"),
ninja::NinjaArg::createRaw("-fsanitize=address"),
ninja::NinjaArg::createRaw("-fsanitize=undefined")
};
@@ -417,7 +416,8 @@ namespace backend
ninja::NinjaArg::createRaw("-D_FORTIFY_SOURCE=2"),
ninja::NinjaArg::createRaw("-D_GLIBCXX_ASSERTIONS"),
ninja::NinjaArg::createRaw("-fasynchronous-unwind-tables"),
- ninja::NinjaArg::createRaw("-D_DEBUG")
+ ninja::NinjaArg::createRaw("-D_DEBUG"),
+ ninja::NinjaArg::createRaw("-fno-omit-frame-pointer"),
};
}
case OPT_LEV_RELEASE:
@@ -767,6 +767,10 @@ namespace backend
static string getCompilerLinker(Compiler compiler)
{
+ char *ar = std::getenv("AR");
+ if(ar)
+ return ar;
+
string result;
switch(compiler)
{
@@ -783,17 +787,54 @@ namespace backend
return result;
}
+ enum class RuntimeCompilerType
+ {
+ NONE,
+ OTHER,
+ CLANG,
+ EMSCRIPTEN
+ };
+
Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
- bool isCCompilerClang = false;
- Result<ExecResult> cCompilerVersion = exec(TINYDIR_STRING("cc --version"));
- if(cCompilerVersion && cCompilerVersion.unwrap().exitCode == 0 && cCompilerVersion.unwrap().execStdout.find("clang") != string::npos)
- isCCompilerClang = true;
+ string cCompilerName = getCompilerCExecutable(config.getCompiler());
+ string cppCompilerName = getCompilerCppExecutable(config.getCompiler());
+ string compilerLinker = getCompilerLinker(config.getCompiler());
+
+ RuntimeCompilerType cCompilerType = RuntimeCompilerType::NONE;
+ Result<ExecResult> cCompilerVersion = exec(toFileString(cCompilerName) + TINYDIR_STRING(" --version"));
+ if(cCompilerVersion && cCompilerVersion.unwrap().exitCode == 0)
+ {
+ if(cCompilerVersion.unwrap().execStdout.find("Emscripten") != string::npos)
+ cCompilerType = RuntimeCompilerType::EMSCRIPTEN;
+ else if(cCompilerVersion.unwrap().execStdout.find("clang") != string::npos)
+ cCompilerType = RuntimeCompilerType::CLANG;
+ else
+ cCompilerType = RuntimeCompilerType::OTHER;
+ }
- bool isCppCompilerClang = false;
- Result<ExecResult> cppCompilerVersion = exec(TINYDIR_STRING("c++ --version"));
- if(cppCompilerVersion && cppCompilerVersion.unwrap().exitCode == 0 && cppCompilerVersion.unwrap().execStdout.find("clang") != string::npos)
- isCppCompilerClang = true;
+ RuntimeCompilerType cppCompilerType = RuntimeCompilerType::NONE;
+ Result<ExecResult> cppCompilerVersion = exec(toFileString(cppCompilerName) + TINYDIR_STRING(" --version"));
+ if(cppCompilerVersion && cppCompilerVersion.unwrap().exitCode == 0)
+ {
+ if(cppCompilerVersion.unwrap().execStdout.find("Emscripten") != string::npos)
+ cppCompilerType = RuntimeCompilerType::EMSCRIPTEN;
+ else if(cppCompilerVersion.unwrap().execStdout.find("clang") != string::npos)
+ cppCompilerType = RuntimeCompilerType::CLANG;
+ else
+ cppCompilerType = RuntimeCompilerType::OTHER;
+ }
+
+ if(cCompilerType != RuntimeCompilerType::NONE && cppCompilerType != RuntimeCompilerType::NONE && cCompilerType != cppCompilerType)
+ return Result<bool>::Err("The c and c++ compiler has to be of the same type");
+
+ RuntimeCompilerType compilerType = cCompilerType;
+ if(compilerType == RuntimeCompilerType::NONE)
+ compilerType = cppCompilerType;
+
+ bool sanitize = config.getSanitize();
+ if(compilerType == RuntimeCompilerType::EMSCRIPTEN)
+ sanitize = false;
Result<bool> createBuildDirResult = createDirectoryRecursive(savePath);
if (!createBuildDirResult)
@@ -818,16 +859,16 @@ namespace backend
if(config.packaging && !config.isMainProject())
libraryType = LibraryType::STATIC;
+ // TODO: Emscripten dynamic library support is not good at the moment, remove this once emscripten has been improved
+ if(libraryType == LibraryType::DYNAMIC && compilerType == RuntimeCompilerType::EMSCRIPTEN)
+ libraryType = LibraryType::STATIC;
+
string savePathUtf8 = toUtf8(savePath);
string projectPathUtf8 = toUtf8(config.getProjectPath());
FileString ninjaBuildFilePath = savePath;
ninjaBuildFilePath += TINYDIR_STRING("/build.ninja");
- string cCompilerName = getCompilerCExecutable(config.getCompiler());
- string cppCompilerName = getCompilerCppExecutable(config.getCompiler());
- string compilerLinker = getCompilerLinker(config.getCompiler());
-
ninja::NinjaBuildFile ninjaBuildFile;
string globalIncDir;
@@ -1053,8 +1094,11 @@ namespace backend
vector<ninja::NinjaArg> optimizationFlags = getCompilerOptimizationFlags(config);
compileCCommand.insert(compileCCommand.end(), optimizationFlags.begin(), optimizationFlags.end());
- vector<ninja::NinjaArg> sanitizerFlags = getCompilerSanitizerFlags(config);
- compileCCommand.insert(compileCCommand.end(), sanitizerFlags.begin(), sanitizerFlags.end());
+ if(sanitize)
+ {
+ vector<ninja::NinjaArg> sanitizerFlags = getCompilerSanitizerFlags(config);
+ compileCCommand.insert(compileCCommand.end(), sanitizerFlags.begin(), sanitizerFlags.end());
+ }
compileCppCommand = compileCCommand;
compileCppCommand[0] = ninja::NinjaArg::createRaw(cppCompilerName);
@@ -1101,8 +1145,11 @@ namespace backend
vector<ninja::NinjaArg> optimizationFlags = getCompilerOptimizationFlags(config);
compileCCommand.insert(compileCCommand.end(), optimizationFlags.begin(), optimizationFlags.end());
- vector<ninja::NinjaArg> sanitizerFlags = getCompilerSanitizerFlags(config);
- compileCCommand.insert(compileCCommand.end(), sanitizerFlags.begin(), sanitizerFlags.end());
+ if(sanitize)
+ {
+ vector<ninja::NinjaArg> sanitizerFlags = getCompilerSanitizerFlags(config);
+ compileCCommand.insert(compileCCommand.end(), sanitizerFlags.begin(), sanitizerFlags.end());
+ }
compileCppCommand = compileCCommand;
compileCppCommand.push_back(ninja::NinjaArg("/EHs"));
@@ -1288,7 +1335,7 @@ namespace backend
case Compiler::MINGW_W64:
case Compiler::GCC:
{
- packagingFlags = "-static -static-libgcc -static-libstdc++";
+ packagingFlags = "-static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic";
break;
}
case Compiler::MSVC:
@@ -1319,10 +1366,11 @@ namespace backend
string noUndefinedFlag;
if(!onlyZigFiles)
{
+ bool isCompilerClangLike = (compilerType == RuntimeCompilerType::CLANG) || (compilerType == RuntimeCompilerType::EMSCRIPTEN);
if(usesCppFiles)
- noUndefinedFlag = isCppCompilerClang ? "-Wl,-undefined,error" : "-Wl,--no-undefined,--as-needed";
+ noUndefinedFlag = isCompilerClangLike ? "-Wl,-undefined,error" : "-Wl,--no-undefined,--as-needed";
else
- noUndefinedFlag = isCCompilerClang ? "-Wl,-undefined,error" : "-Wl,--no-undefined,--as-needed";
+ noUndefinedFlag = isCompilerClangLike ? "-Wl,-undefined,error" : "-Wl,--no-undefined,--as-needed";
}
ninja::NinjaVariable zigObjectArgs("object_args");
@@ -1371,10 +1419,15 @@ namespace backend
ninja::NinjaArg::createRaw(noUndefinedFlag)
});
+ if(compilerType == RuntimeCompilerType::EMSCRIPTEN)
+ {
+ buildExeArgs.push_back(ninja::NinjaArg::createRaw("-s MAIN_MODULE=1"));
+ }
+
if(!rpath.empty())
buildExeArgs.push_back(ninja::NinjaArg("-Wl,-rpath," + rpath));
- if(config.getSanitize())
+ if(sanitize)
{
buildExeArgs.insert(buildExeArgs.end(), {
ninja::NinjaArg::createRaw("-lasan"),
@@ -1451,7 +1504,7 @@ namespace backend
ninja::NinjaArg::createRaw("-luserenv"),
ninja::NinjaArg::createRaw("-lopengl32"),
ninja::NinjaArg::createRaw("-lglu32"),
- ninja::NinjaArg::createRaw("-Wl,-Bstatic -lwinpthread"),
+ ninja::NinjaArg::createRaw("-Wl,-Bstatic -lwinpthread -Wl,-Bdynamic"),
ninja::NinjaArg::createRaw("-lshell32")
});
}
@@ -1551,7 +1604,10 @@ namespace backend
case Compiler::MINGW_W64:
case Compiler::GCC:
{
- generatedFile = "lib" + config.getPackageName() + "." + CONFIG_DYNAMIC_LIB_FILE_EXTENSION;
+ const char *fileExtension = CONFIG_DYNAMIC_LIB_FILE_EXTENSION;
+ if(compilerType == RuntimeCompilerType::EMSCRIPTEN)
+ fileExtension = "wasm";
+ generatedFile = "lib" + config.getPackageName() + "." + fileExtension;
break;
}
case Compiler::MSVC:
@@ -1594,7 +1650,12 @@ namespace backend
ninja::NinjaArg::createRaw(noUndefinedFlag)
});
- if(config.getSanitize())
+ if(compilerType == RuntimeCompilerType::EMSCRIPTEN)
+ {
+ buildDynamicArgs.push_back(ninja::NinjaArg::createRaw("-s SIDE_MODULE=1"));
+ }
+
+ if(sanitize)
{
buildDynamicArgs.insert(buildDynamicArgs.end(), {
ninja::NinjaArg::createRaw("-lasan"),
@@ -1665,7 +1726,7 @@ namespace backend
ninja::NinjaArg::createRaw("-luserenv"),
ninja::NinjaArg::createRaw("-lopengl32"),
ninja::NinjaArg::createRaw("-lglu32"),
- ninja::NinjaArg::createRaw("-Wl,-Bstatic -lwinpthread"),
+ ninja::NinjaArg::createRaw("-Wl,-Bstatic -lwinpthread -Wl,-Bdynamic"),
ninja::NinjaArg::createRaw("-lshell32")
});
}
@@ -1697,7 +1758,7 @@ namespace backend
if (!buildResult)
return buildResult;
- if(config.isMainProject())
+ if((config.isMainProject() && !config.shouldBuildTests()) || config.isTest())
{
buildResult = buildCompilationDatabase(savePath, config.getProjectPath());
if(!buildResult)
@@ -1820,14 +1881,6 @@ namespace backend
Result<bool> buildFileResult = ninja.build(sibsTestConfig, buildPath.c_str());
if (!buildFileResult)
return buildFileResult;
-
- // Main projects test should also have compilation database, so we can use it inside IDE
- if(config.isMainProject())
- {
- buildFileResult = buildCompilationDatabase(buildPath.c_str(), testSourceDirNative);
- if(!buildFileResult)
- return buildFileResult;
- }
if(!zigTest)
{