Adding a cmake-toolchain option for easy cross-compilation with kdesrc-build
Feature proposal
kdesrc-build
should support a cmake-toolchain
option to configure the appropriate toolchain to use for compiling/linking etc. when invoking CMake. This would let users use kdesrc-build
for cross-compiling, simplifying the SDK story for Plasma Mobile considerably. See also: https://cmake.org/cmake/help/v3.6/manual/cmake-toolchains.7.html
One important consideration here is that in CMake terms, the toolchain file is just a config file which is used to inject various CMake settings. That means it is potentially useful not just for setting up the compilers but also for setting up various package search paths such as CMAKE_MODULE_PATH
, CMAKE_PREFIX_PATH
, or PKG_CONFIG_PATH
as well.
Context
Based on discussion on Matrix/IRC:
Bhushan Shah wrote:
One of the things I stumbled upon is kdesrc-build wanting to mess with paths When you cross compile stuff, you want to leave setting up paths and stuff to the well cmake toolchain and not mess with it yourself Since you can't actually run cross compiled binaries in the host system I wonder if I can disable this behavior of kdesrc-build?
Background of what I'm working on: currently whenever someone wants to write a app for the plasma mobile device, roughly solution is to basically build things natively on device. It doesn't scale very well tbh And I'm working on providing a native SDK solution which can easily cross compile things
For short term I migrated to my own script in loop which passes the correct parameters and ninja builds things. But ideally I would like to migrate to the kdesrc-build
Outline
I think this could be patterned off of the recent cmake-generator
support:
- Introduce an option
cmake-toolchain /foo
which is a high level equivalent to specifying-DCMAKE_TOOLCHAIN_FILE=/foo
. - Support scrubbing/inferring the
cmake-toolchain
option fromcmake-options
, similar to what is done with-G
forcmake-generator
- ... Determine which environment variables should not be touched, suppress or alter calls to queue environment variables accordingly.
cmake-options
?
Why another option, why not re-use Answer: scripting. If the toolchain is passed through a dedicated option, then it can be easily injected via the commandline using --set-module-option-value "global,cmake-toolchain,/path/to/toolchain/file.cmake"
.
In turn, this makes it easier for other programs/scripts to drive kdesrc-build
, e.g.: running kdesrc-build
in a loop, cross-compiling for multiple architectures one after the other.
Changes needed
In addition to the introduction of a cmake-toolchain
option, point 3 of the outline means that at least the following functions need to be updated in kdesrc-build
:
ksb::Module::setupEnvironment
sub setupEnvironment
{
my $self = assert_isa(shift, 'ksb::Module');
my $ctx = $self->buildContext();
my $kdedir = $self->getOption('kdedir');
my $qtdir = $self->getOption('qtdir');
my $prefix = $self->installationPath();
# Add global set-envs and context
$self->buildContext()->applyUserEnvironment();
# Ensure the platform libraries we're building can be found, as long as they
# are not the system's own libraries.
for my $platformDir ($qtdir, $kdedir) {
next unless $platformDir; # OK, assume system platform is usable
next if $platformDir eq '/usr'; # Don't 'fix' things if system platform
# manually set
$ctx->prependEnvironmentValue('PKG_CONFIG_PATH', "$platformDir/lib/pkgconfig");
$ctx->prependEnvironmentValue('LD_LIBRARY_PATH', "$platformDir/lib");
$ctx->prependEnvironmentValue('PATH', "$platformDir/bin");
}
ksb::BuildSystem::KDE4::prepareModuleBuildEnvironment
sub prepareModuleBuildEnvironment
{
my ($self, $ctx, $module, $prefix) = @_;
# Avoid moving /usr up in env vars
if ($prefix ne '/usr') {
# Find the normal CMake "config" mode files for find_package()
$ctx->prependEnvironmentValue('CMAKE_PREFIX_PATH', $prefix);
# Try to ensure that older "module" mode find_package() calls also point to right directory
$ctx->prependEnvironmentValue('CMAKE_MODULE_PATH', "$prefix/lib64/cmake:$prefix/lib/cmake");
$ctx->prependEnvironmentValue('XDG_DATA_DIRS', "$prefix/share");
}
my $qtdir = $module->getOption('qtdir');
if ($qtdir && $qtdir ne $prefix) {
# Ensure we can find Qt5's own CMake modules
$ctx->prependEnvironmentValue('CMAKE_PREFIX_PATH', $qtdir);
$ctx->prependEnvironmentValue('CMAKE_MODULE_PATH', "$qtdir/lib/cmake");
}
}
ksb::l10nSystem::prepareModuleBuildEnvironment
I'm not certain, but this may also be affected.
sub prepareModuleBuildEnvironment
{
my ($ctx, $module, $prefix) = @_;
$ctx->prependEnvironmentValue('CMAKE_PREFIX_PATH', $prefix);
}