aboutsummaryrefslogtreecommitdiff
path: root/backend/ninja/Ninja.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-10-05 05:02:49 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-06 07:39:33 +0200
commit5250cb90406693163763a214af95f670e0e3a4e0 (patch)
tree7025c762d4f53aebfdc140d615306f558fa9b69a /backend/ninja/Ninja.cpp
parent3059b1cb8d701cf23f3e04a8a8fdcfcaa6a397fb (diff)
Add cross compilation (mingw-w64 x86_64)
Currently only cross compiling from linux64 to win64 works. Need to test cross compilation more, currently the cross compilation uses same profile as GCC, is that correct?
Diffstat (limited to 'backend/ninja/Ninja.cpp')
-rw-r--r--backend/ninja/Ninja.cpp148
1 files changed, 121 insertions, 27 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 4495bd4..27608cc 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -98,6 +98,7 @@ namespace backend
string result;
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
result = "'-I";
@@ -123,6 +124,7 @@ namespace backend
{
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
return "'-D" + name + "=" + value + "'";
@@ -143,6 +145,7 @@ namespace backend
string result;
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
result = "-o ";
@@ -166,6 +169,7 @@ namespace backend
{
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
switch(cVersion)
@@ -193,6 +197,7 @@ namespace backend
{
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
switch(cppVersion)
@@ -223,6 +228,7 @@ namespace backend
{
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC: return ".o";
case Compiler::MSVC: return ".obj";
default: return nullptr;
@@ -387,6 +393,7 @@ namespace backend
{
switch (config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
switch (config.getOptimizationLevel())
@@ -460,6 +467,7 @@ namespace backend
switch (compiler)
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
includeStartStr = "-I";
@@ -693,6 +701,60 @@ namespace backend
return result;
}
+ static string getCompilerCExecutable(Compiler compiler)
+ {
+ string result;
+ switch(compiler)
+ {
+ case Compiler::GCC:
+ result = "cc";
+ break;
+ case Compiler::MINGW_W64:
+ result = "x86_64-w64-mingw32-cc";
+ break;
+ case Compiler::MSVC:
+ result = "cl.exe";
+ break;
+ }
+ return result;
+ }
+
+ static string getCompilerCppExecutable(Compiler compiler)
+ {
+ string result;
+ switch(compiler)
+ {
+ case Compiler::GCC:
+ result = "c++";
+ break;
+ case Compiler::MINGW_W64:
+ result = "x86_64-w64-mingw32-c++";
+ break;
+ case Compiler::MSVC:
+ result = "cl.exe";
+ break;
+ }
+ return result;
+ }
+
+ static string getCompilerLinker(Compiler compiler)
+ {
+ string result;
+ switch(compiler)
+ {
+ case Compiler::GCC:
+ result = "ar";
+ break;
+ case Compiler::MINGW_W64:
+ result = "x86_64-w64-mingw32-ar";
+ break;
+ case Compiler::MSVC:
+ result = "lib.exe";
+ break;
+ }
+ return result;
+ }
+
Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
bool isCCompilerClang = false;
@@ -734,6 +796,10 @@ namespace backend
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;
@@ -764,12 +830,10 @@ namespace backend
parentGlobalIncludeDirCallback(globalIncludeDir);
};
-#if OS_TYPE == OS_TYPE_LINUX
// TODO: Allow configuring default linking flags. Maybe have `package.useThreads = false` to disable this flag
- string allLinkerFlags = "-pthread";
-#else
- string allLinkerFlags = "";
-#endif
+ string allLinkerFlags;
+ if(isSamePlatformFamily(config.platform, PLATFORM_LINUX))
+ allLinkerFlags = "-pthread";
// 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
@@ -866,6 +930,7 @@ namespace backend
switch(config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
vector<ninja::NinjaArg> baseCompileCArgs;
@@ -875,7 +940,7 @@ namespace backend
{
baseCompileCArgs.insert(baseCompileCArgs.end(), {
ninja::NinjaArg("ccache"),
- ninja::NinjaArg("cc"),
+ ninja::NinjaArg(cCompilerName),
ninja::NinjaArg("-c"),
ninja::NinjaArg("-fpie"),
ninja::NinjaArg("$in"),
@@ -889,7 +954,7 @@ namespace backend
{
baseCompileCArgs.insert(baseCompileCArgs.end(), {
ninja::NinjaArg("ccache"),
- ninja::NinjaArg("cc"),
+ ninja::NinjaArg(cCompilerName),
ninja::NinjaArg("-c"),
ninja::NinjaArg("-fpic"),
ninja::NinjaArg("$in"),
@@ -936,7 +1001,7 @@ namespace backend
compileCCommand.insert(compileCCommand.end(), sanitizerFlags.begin(), sanitizerFlags.end());
compileCppCommand = compileCCommand;
- compileCppCommand[1] = ninja::NinjaArg("c++");
+ compileCppCommand[1] = ninja::NinjaArg(cppCompilerName);
compileCppCommand.insert(compileCppCommand.end(), {
ninja::NinjaArg("-fexceptions"),
ninja::NinjaArg("-Wnon-virtual-dtor")
@@ -1001,6 +1066,7 @@ namespace backend
switch(config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
compileCRule->depFile = "$out.d";
@@ -1015,6 +1081,8 @@ namespace backend
}
}
+ bool crossOsCompiling = !isSamePlatformFamily(config.platform, SYSTEM_PLATFORM);
+
// TODO: Specify -mconsole or -mwindows for windows.
// TODO: Convert sibs defines to const variables in a zig file that other zig files can include (like a config file).
@@ -1026,6 +1094,9 @@ namespace backend
ninja::NinjaArg::createRaw("$globalIncDirZig")
};
+ if(isSamePlatformFamily(SYSTEM_PLATFORM, PLATFORM_LINUX) && isSamePlatformFamily(config.platform, PLATFORM_WIN))
+ commonZigArgs.push_back(ninja::NinjaArg::createRaw("--target-os windows --target-arch x86_64 --target-environ gnu --libc-lib-dir /usr/x86_64-w64-mingw32/lib --libc-static-lib-dir /usr/x86_64-w64-mingw32/lib"));
+
// TODO: Remove this if project does not depend on c libraries or project only has .zig files
if(!config.packaging)
commonZigArgs.push_back(ninja::NinjaArg::createRaw("--library c"));
@@ -1112,6 +1183,7 @@ namespace backend
onlyZigFiles = false;
}
+ bool containsZigFiles = false;
for(const sibs::SourceFile &sourceFile : sourceFiles)
{
string objectName;
@@ -1136,6 +1208,7 @@ namespace backend
case sibs::Language::ZIG:
{
// Already built above
+ containsZigFiles = true;
break;
}
default:
@@ -1147,11 +1220,15 @@ namespace backend
objectNames.emplace_back(move(objectName));
}
+ if(containsZigFiles && isSamePlatformFamily(config.platform, PLATFORM_WIN) && !isSamePlatformFamily(SYSTEM_PLATFORM, PLATFORM_WIN))
+ return Result<bool>::Err("Cross compiling a project with zig files from a non-windows platform to windows is currently not supported because zig doesn't support libc when cross compiling");
+
string packagingFlags;
if(config.packaging)
{
switch(config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
packagingFlags = "-static -static-libgcc -static-libstdc++";
@@ -1164,6 +1241,14 @@ namespace backend
}
}
}
+ else
+ {
+ // By statically compiling when using mingw w64, we dont have to bundle our application with several runtime dlls
+ if(config.getCompiler() == Compiler::MINGW_W64)
+ {
+ packagingFlags = "-static -static-libgcc -static-libstdc++";
+ }
+ }
// TODO: For now zig projects (zig object files) are built with c/c++ compiler,
// they should be built with zig if project only contains zig files.
@@ -1196,7 +1281,7 @@ namespace backend
{
vector<ninja::NinjaArg> buildExeArgs;
string executableName = config.getPackageName();
- if(OS_FAMILY == OS_FAMILY_WINDOWS)
+ if(isSamePlatformFamily(config.platform, PLATFORM_WIN))
executableName += ".exe";
if(onlyZigFiles)
{
@@ -1218,12 +1303,13 @@ namespace backend
{
switch (config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
string rpath = extractDynamicLibDirsFromLinkerFlags(dynamicLinkerFlags);
buildExeArgs.insert(buildExeArgs.end(), {
ninja::NinjaArg::createRaw("ccache"),
- ninja::NinjaArg::createRaw(usesCppFiles ? "c++" : "cc"),
+ ninja::NinjaArg::createRaw(usesCppFiles ? cppCompilerName : cCompilerName),
ninja::NinjaArg::createRaw("-o"),
ninja::NinjaArg::createRaw("$out"),
ninja::NinjaArg::createRaw("$in"),
@@ -1252,10 +1338,13 @@ namespace backend
ninja::NinjaArg::createRaw("-lm")
});
#else
- buildExeArgs.insert(buildExeArgs.end(), {
- ninja::NinjaArg::createRaw("-ldl"),
- ninja::NinjaArg::createRaw("-lm")
- });
+ if(!isSamePlatformFamily(config.platform, PLATFORM_WIN))
+ {
+ buildExeArgs.insert(buildExeArgs.end(), {
+ ninja::NinjaArg::createRaw("-ldl"),
+ ninja::NinjaArg::createRaw("-lm")
+ });
+ }
#endif
break;
}
@@ -1263,7 +1352,7 @@ namespace backend
{
// 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("cl.exe"),
+ ninja::NinjaArg::createRaw(cppCompilerName),
ninja::NinjaArg::createRaw("$in"),
ninja::NinjaArg::createRaw("/Fe$out"),
ninja::NinjaArg::createRaw("Ws2_32.lib"),
@@ -1299,10 +1388,7 @@ namespace backend
buildExeRule->build(objectNames, executableName, {});
}
- projectGeneratedBinary += config.getPackageName();
- #if OS_FAMILY == OS_FAMILY_WINDOWS
- projectGeneratedBinary += ".exe";
- #endif
+ projectGeneratedBinary += executableName;
projectGeneratedBinary += "\"";
break;
}
@@ -1312,6 +1398,7 @@ namespace backend
string generatedFile;
switch (config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
generatedFile = "lib" + config.getPackageName() + ".a";
@@ -1341,10 +1428,11 @@ namespace backend
{
switch (config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
buildStaticArgs.insert(buildStaticArgs.end(), {
- ninja::NinjaArg::createRaw("ar"),
+ ninja::NinjaArg::createRaw(compilerLinker),
ninja::NinjaArg::createRaw("rcs"),
ninja::NinjaArg::createRaw("$out"),
ninja::NinjaArg::createRaw("$in")
@@ -1354,7 +1442,7 @@ namespace backend
case Compiler::MSVC:
{
buildStaticArgs.insert(buildStaticArgs.end(), {
- ninja::NinjaArg::createRaw("lib.exe"),
+ ninja::NinjaArg::createRaw(compilerLinker),
ninja::NinjaArg::createRaw("/OUT:$out"),
ninja::NinjaArg::createRaw("$in")
});
@@ -1389,6 +1477,7 @@ namespace backend
string generatedFile;
switch (config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
generatedFile = "lib" + config.getPackageName() + ".so";
@@ -1421,11 +1510,12 @@ namespace backend
{
switch (config.getCompiler())
{
+ case Compiler::MINGW_W64:
case Compiler::GCC:
{
buildDynamicArgs.insert(buildDynamicArgs.end(), {
ninja::NinjaArg::createRaw("ccache"),
- ninja::NinjaArg::createRaw(usesCppFiles ? "c++" : "cc"),
+ ninja::NinjaArg::createRaw(usesCppFiles ? cppCompilerName : cCompilerName),
ninja::NinjaArg::createRaw("$in"),
ninja::NinjaArg::createRaw("-shared"),
ninja::NinjaArg("-Wl,-soname," + generatedFile),
@@ -1448,17 +1538,20 @@ namespace backend
ninja::NinjaArg::createRaw("-lm")
});
#else
- buildDynamicArgs.insert(buildDynamicArgs.end(), {
- ninja::NinjaArg::createRaw("-ldl"),
- ninja::NinjaArg::createRaw("-lm")
- });
+ if(!isSamePlatformFamily(config.platform, PLATFORM_WIN))
+ {
+ buildDynamicArgs.insert(buildDynamicArgs.end(), {
+ ninja::NinjaArg::createRaw("-ldl"),
+ ninja::NinjaArg::createRaw("-lm")
+ });
+ }
#endif
break;
}
case Compiler::MSVC:
{
buildDynamicArgs.insert(buildDynamicArgs.end(), {
- ninja::NinjaArg::createRaw("lib.exe"),
+ ninja::NinjaArg::createRaw(compilerLinker),
ninja::NinjaArg::createRaw("/OUT:$out"),
ninja::NinjaArg::createRaw("$in"),
ninja::NinjaArg::createRaw("Ws2_32.lib"),
@@ -1567,6 +1660,7 @@ namespace backend
FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative, config.getOptimizationLevel());
+ sibsTestConfig.platform = config.platform;
sibsTestConfig.setSanitize(config.getSanitize());
sibsTestConfig.zigTestFiles = move(config.zigTestFiles);
sibsTestConfig.zigTestAllFiles = config.zigTestAllFiles;