aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
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 'src')
-rw-r--r--src/FileUtil.cpp27
-rw-r--r--src/GlobalLib.cpp2
-rw-r--r--src/PkgConfig.cpp17
-rw-r--r--src/Platform.cpp5
-rw-r--r--src/main.cpp53
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);
}