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 /src | |
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 'src')
-rw-r--r-- | src/FileUtil.cpp | 27 | ||||
-rw-r--r-- | src/GlobalLib.cpp | 2 | ||||
-rw-r--r-- | src/PkgConfig.cpp | 17 | ||||
-rw-r--r-- | src/Platform.cpp | 5 | ||||
-rw-r--r-- | src/main.cpp | 53 |
5 files changed, 94 insertions, 10 deletions
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp index 498f638..e317304 100644 --- a/src/FileUtil.cpp +++ b/src/FileUtil.cpp @@ -1,5 +1,6 @@ #include "../include/FileUtil.hpp" #include <cstdio> +#include <fstream> #if OS_FAMILY == OS_FAMILY_POSIX #include <unistd.h> @@ -497,4 +498,30 @@ namespace sibs return pathIndex == path.size() && otherPathIndex == otherPath.size(); } + + Result<bool> copyFile(const FileString &src, const FileString &dst) + { + ifstream srcFile(src.c_str(), ios::binary); + if(!srcFile) + { + string errMsg = "Failed to open file "; + errMsg += toUtf8(src); + errMsg += ", reason: "; + errMsg += strerror(errno); + return Result<bool>::Err(errMsg); + } + + ofstream dstFile(dst.c_str(), ios::binary); + if(!dstFile) + { + string errMsg = "Failed to create/overwrite file "; + errMsg += toUtf8(dst); + errMsg += ", reason: "; + errMsg += strerror(errno); + return Result<bool>::Err(errMsg); + } + + dstFile << srcFile.rdbuf(); + return Result<bool>::Ok(true); + } } diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp index a175e02..242e621 100644 --- a/src/GlobalLib.cpp +++ b/src/GlobalLib.cpp @@ -202,7 +202,9 @@ namespace sibs } SibsConfig sibsConfig(parentConfig.getCompiler(), packageDir, parentConfig.getOptimizationLevel(), false); + sibsConfig.platform = parentConfig.platform; sibsConfig.packaging = parentConfig.packaging; + sibsConfig.bundling = parentConfig.bundling; Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig); if (result.isErr()) return result; diff --git a/src/PkgConfig.cpp b/src/PkgConfig.cpp index faed146..9efc238 100644 --- a/src/PkgConfig.cpp +++ b/src/PkgConfig.cpp @@ -4,12 +4,14 @@ using namespace std; +static sibs::FileString pkgConfigPath = "pkg-config"; + // TODO: Do not use pkg-config program. The same functionality can easily be achieved // by reading files in /usr/share/pkgconfig // Or is there no downside to calling pkg-config program? namespace sibs { - string trimRight(const string &input) + static string trimRight(const string &input) { for(int i = input.size() - 1; i >= 0; --i) { @@ -18,6 +20,11 @@ namespace sibs } return ""; } + + void PkgConfig::setPkgConfigPath(const FileString &path) + { + pkgConfigPath = path; + } Result<bool> PkgConfig::validatePkgConfigPackageVersionExists(PackageListDependency *dependency) { @@ -34,7 +41,7 @@ namespace sibs Result<bool> PkgConfig::validatePackageExists(const string &name) { - FileString command = TINYDIR_STRING("pkg-config --exists '"); + FileString command = pkgConfigPath + TINYDIR_STRING(" --exists '"); command += toFileString(name); command += TINYDIR_STRING("'"); Result<ExecResult> execResult = exec(command.c_str()); @@ -68,7 +75,7 @@ namespace sibs // Use --modversion instead and check if the version returned is newer or equal to dependency version. // This way we can output installed version vs expected dependency version - FileString command = TINYDIR_STRING("pkg-config '--atleast-version="); + FileString command = pkgConfigPath + TINYDIR_STRING(" '--atleast-version="); command += toFileString(version); command += TINYDIR_STRING("' '"); command += toFileString(name); @@ -111,7 +118,7 @@ namespace sibs args += "'"; } - FileString command = TINYDIR_STRING("pkg-config --libs"); + FileString command = pkgConfigPath + TINYDIR_STRING(" --libs"); command += toFileString(args); Result<ExecResult> execResult = exec(command.c_str()); if(execResult.isErr()) @@ -154,7 +161,7 @@ namespace sibs args += "'"; } - FileString command = TINYDIR_STRING("pkg-config --cflags"); + FileString command = pkgConfigPath + TINYDIR_STRING(" --cflags"); command += toFileString(args); Result<ExecResult> execResult = exec(command.c_str()); if(execResult.isErr()) diff --git a/src/Platform.cpp b/src/Platform.cpp index 44f42db..2df019c 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -41,4 +41,9 @@ namespace sibs return it->second; return PLATFORM_INVALID; } + + bool isSamePlatformFamily(Platform a, Platform b) + { + return a & b; + } }
\ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e55014e..3ffb264 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,6 +9,7 @@ #include "../include/CmakeModule.hpp" #include "../backend/BackendUtils.hpp" #include "../backend/ninja/Ninja.hpp" +#include "../include/PkgConfig.hpp" using namespace std; using namespace sibs; @@ -118,18 +119,20 @@ static void usage() static void usageBuild() { - printf("Usage: sibs build [project_path] [--debug|--release] [--sanitize]\n\n"); + printf("Usage: sibs build [project_path] [--debug|--release] [--sanitize] [--platform <platform>]\n\n"); printf("Build a sibs project\n\n"); printf("Options:\n"); printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current directory)\n"); printf(" --debug|--release\t\tOptimization level to build project and dependencies with (if not a system package) - Optional (default: --debug)\n"); printf(" --sanitize\t\tAdd runtime address/undefined behavior sanitization. Program can be up to 3 times slower and use 10 times as much RAM. Ignored if compiler doesn't support sanitization - Optional (default: disabled)\n"); + printf(" --platform\t\tThe platform to build for - Optional (default: the running platform). Platform can be either linux32, linux64, win32 or win64\n"); printf("Examples:\n"); printf(" sibs build\n"); printf(" sibs build dirA/dirB\n"); printf(" sibs build --release\n"); printf(" sibs build dirA --release\n"); printf(" sibs build --sanitize\n"); + printf(" sibs build --release --platform win64\n"); exit(1); } @@ -150,7 +153,7 @@ static void usageNew() static void usageTest() { - printf("Usage: sibs test [project_path] [--no-sanitize] [--file filepath...|--all-files]\n\n"); + printf("Usage: sibs test [project_path] [--no-sanitize] [--file <filepath>...|--all-files]\n\n"); printf("Build and run tests for a sibs project\n\n"); printf("Options:\n"); printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current directory)\n"); @@ -428,12 +431,10 @@ static int buildProject(const FileString &projectPath, const FileString &project static int buildProject(int argc, const _tinydir_char_t **argv) { - if(argc > 3) - usageBuild(); - OptimizationLevel optimizationLevel = OPT_LEV_NONE; FileString projectPath; bool sanitize = false; + const _tinydir_char_t *platformName = nullptr; for(int i = 0; i < argc; ++i) { @@ -460,6 +461,24 @@ static int buildProject(int argc, const _tinydir_char_t **argv) { sanitize = true; } + else if(_tinydir_strcmp(arg, TINYDIR_STRING("--platform")) == 0) + { + if(i == argc - 1) + { + ferr << "Error: Expected platform to target after --platform" << endl; + usageBuild(); + } + + ++i; + arg = argv[i]; + + if(platformName) + { + ferr << "Error: Platform defined twice. First as " << platformName << " then as " << arg << endl; + usageBuild(); + } + platformName = arg; + } else if(_tinydir_strncmp(arg, TINYDIR_STRING("--"), 2) == 0) { ferr << "Error: Invalid argument " << arg << endl; @@ -479,6 +498,24 @@ static int buildProject(int argc, const _tinydir_char_t **argv) if(optimizationLevel == OPT_LEV_NONE) optimizationLevel = OPT_LEV_DEBUG; + if(!platformName) + platformName = SYSTEM_PLATFORM_NAME; + + string platformUtf8 = toUtf8(platformName); + Platform platform = getPlatformByName(StringView(platformUtf8.data(), platformUtf8.size())); + if(platform == PLATFORM_INVALID) + { + ferr << "Invalid platform " << platformName << endl; + usageBuild(); + } + + bool crossCompileLinux64ToWin64 = (SYSTEM_PLATFORM == PLATFORM_LINUX64 && platform == PLATFORM_WIN64); + if(platform != SYSTEM_PLATFORM && !crossCompileLinux64ToWin64) + { + ferr << "Cross compilation is currently only supported from linux64 to win64" << endl; + exit(33); + } + // TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found if(projectPath.empty()) projectPath = TINYDIR_STRING("."); @@ -503,12 +540,18 @@ static int buildProject(int argc, const _tinydir_char_t **argv) // by passing argument to `sibs build` #if OS_FAMILY == OS_FAMILY_POSIX Compiler compiler = Compiler::GCC; + if(crossCompileLinux64ToWin64) + { + compiler = Compiler::MINGW_W64; + PkgConfig::setPkgConfigPath(TINYDIR_STRING("x86_64-w64-mingw32-pkg-config")); + } #else Compiler compiler = Compiler::MSVC; #endif SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, false); sibsConfig.showWarnings = true; + sibsConfig.platform = platform; sibsConfig.setSanitize(sanitize); return buildProject(projectPath, projectConfFilePath, sibsConfig); } |