diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-10-05 05:02:49 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-07-06 07:39:33 +0200 |
commit | 5250cb90406693163763a214af95f670e0e3a4e0 (patch) | |
tree | 7025c762d4f53aebfdc140d615306f558fa9b69a /backend/ninja | |
parent | 3059b1cb8d701cf23f3e04a8a8fdcfcaa6a397fb (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')
-rw-r--r-- | backend/ninja/Ninja.cpp | 148 |
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; |