Skip to content

Commit

Permalink
Merge pull request mesonbuild#7816 from mensinda/cmCross
Browse files Browse the repository at this point in the history
cmake: Cross compilation support
  • Loading branch information
jpakkane authored Oct 13, 2020
2 parents 55cf399 + f5c9bf9 commit 3372c58
Show file tree
Hide file tree
Showing 37 changed files with 605 additions and 282 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/nonative.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ jobs:
apt-get -y autoremove
- uses: actions/checkout@v2
- name: Run tests
run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./run_tests.py $CI_ARGS --cross ubuntu-armhf.txt --cross-only'
run: bash -c 'source /ci/env_vars.sh; cd $GITHUB_WORKSPACE; ./run_tests.py $CI_ARGS --cross ubuntu-armhf.json --cross-only'
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ matrix:
# Also hijack one cross build to test long commandline handling codepath (and avoid overloading Travis)
- os: linux
compiler: gcc
env: RUN_TESTS_ARGS="--cross ubuntu-armhf.txt --cross linux-mingw-w64-64bit.txt" MESON_RSP_THRESHOLD=0
env: RUN_TESTS_ARGS="--cross ubuntu-armhf.json --cross linux-mingw-w64-64bit.json" MESON_RSP_THRESHOLD=0
- os: linux
compiler: gcc
env: RUN_TESTS_ARGS="--cross ubuntu-armhf.txt --cross linux-mingw-w64-64bit.txt" MESON_ARGS="--unity=on"
env: RUN_TESTS_ARGS="--cross ubuntu-armhf.json --cross linux-mingw-w64-64bit.json" MESON_ARGS="--unity=on"

before_install:
- python ./skip_ci.py --base-branch-env=TRAVIS_BRANCH --is-pull-env=TRAVIS_PULL_REQUEST
Expand Down
5 changes: 5 additions & 0 deletions ci/travis_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ fi
source /ci/env_vars.sh
cd /root
update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix
update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix
./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS
#./upload.sh
Expand Down
7 changes: 7 additions & 0 deletions cross/linux-mingw-w64-32bit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"file": "linux-mingw-w64-32bit.txt",
"tests": ["common", "cmake"],
"env": {
"WINEPATH": "/usr/lib/gcc/i686-w64-mingw32/9.2-posix;/usr/i686-w64-mingw32/bin;/usr/i686-w64-mingw32/lib"
}
}
8 changes: 8 additions & 0 deletions cross/linux-mingw-w64-32bit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,11 @@ system = 'windows'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'

[cmake]

CMAKE_BUILD_WITH_INSTALL_RPATH = 'ON'
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM = 'NEVER'
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY = 'ONLY'
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE = 'ONLY'
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE = 'ONLY'
7 changes: 7 additions & 0 deletions cross/linux-mingw-w64-64bit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"file": "linux-mingw-w64-64bit.txt",
"tests": ["common", "cmake"],
"env": {
"WINEPATH": "/usr/lib/gcc/x86_64-w64-mingw32/9.2-posix;/usr/x86_64-w64-mingw32/bin;/usr/x86_64-w64-mingw32/lib"
}
}
8 changes: 8 additions & 0 deletions cross/linux-mingw-w64-64bit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

[cmake]

CMAKE_BUILD_WITH_INSTALL_RPATH = 'ON'
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM = 'NEVER'
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY = 'ONLY'
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE = 'ONLY'
CMAKE_FIND_ROOT_PATH_MODE_PACKAGE = 'ONLY'
5 changes: 5 additions & 0 deletions cross/ubuntu-armhf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"file": "ubuntu-armhf.txt",
"tests": ["common"],
"env": {}
}
37 changes: 37 additions & 0 deletions docs/markdown/CMake-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,43 @@ Options that are not set won't affect the generated subproject. So, if for
instance, `set_install` was not called then the values extracted from CMake will
be used.

### Cross compilation

*New in 0.56.0*

Meson will try to automatically guess most of the required CMake toolchain
variables from existing entries in the cross and native files. These variables
will be stored in an automatically generate CMake toolchain file in the build
directory. The remaining variables that can't be guessed can be added by the
user in the `[cmake]` cross/native file section (*new in 0.56.0*).

Adding a manual CMake toolchain file is also supported with the
`cmake_toolchain_file` setting in the `[properties]` section. Directly setting
a CMake toolchain file with `-DCMAKE_TOOLCHAIN_FILE=/path/to/some/Toolchain.cmake`
in the `meson.build` is **not** supported since the automatically generated
toolchain file is also used by Meson to inject arbitrary code into CMake to
enable the CMake subproject support.

The closest configuration to only using a manual CMake toolchain file would be
to set these options in the machine file:

```ini
[properties]

cmake_toolchain_file = '/path/to/some/Toolchain.cmake'
cmake_defaults = false

[cmake]

# No entries in this section
```

This will result in a toolchain file with just the bare minimum to enable the
CMake subproject support and `include()` the `cmake_toolchain_file` as the
last instruction.

For more information see the [cross and native file specification](Machine-files.md).

## CMake configuration files

### cmake.write_basic_package_version_file()
Expand Down
57 changes: 57 additions & 0 deletions docs/markdown/Machine-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The following sections are allowed:
- binaries
- paths
- properties
- cmake
- project options
- built-in options

Expand Down Expand Up @@ -203,6 +204,62 @@ section may contain random key value pairs accessed using the
properties section has been deprecated, and should be put in the built-in
options section.

#### Supported properties

This is a non exhaustive list of supported variables in the `[properties]`
section.

- `cmake_toolchain_file` specifies an absoulte path to an already existing
CMake toolchain file that will be loaded with `include()` as the last
instruction of the automatically generated CMake toolchain file from meson.
(*new in 0.56.0*)
- `cmake_defaults` is a boolean that specifies whether meson should automatically
generate default toolchain varaibles from other sections (`binaries`,
`host_machine`, etc.) in the machine file. Defaults are always overwritten
by variables set in the `[cmake]` section. The default is `true`. (*new in 0.56.0*)
- `cmake_skip_compiler_test` is an enum that specifies when meson should
automatically generate toolchain variables to skip the CMake compiler
sanity checks. This only has an effect if `cmake_defaults` is `true`.
Supported values are `always`, `never`, `dep_only`. The default is `dep_only`.
(*new in 0.56.0*)
- `cmake_use_exe_wrapper` is a boolean that controlls whether to use the
`exe_wrapper` specified in `[binaries]` to run generated executables in CMake
subprojects. This setting has no effect if the `exe_wrapper` was not specified.
The default value is `true`. (*new in 0.56.0*)

### CMake variables

*New in 0.56.0*

All variables set in the `[cmake]` section will be added to the generate CMake
toolchain file used for both CMake dependencies and CMake subprojects. The type
of each entry must be either a string or a list of strings.

**Note:** All occurances of `\` in the value of all keys will be replaced with
a `/` since CMake has a lot of issues with correctly escaping `\` when
dealing with variables (even in cases where a path in `CMAKE_C_COMPILER`
is correctly escaped, CMake will still trip up internaly for instance)

A custom toolchain file should be used (via the `cmake_toolchain_file`
property) if `\` support is required.

```ini
[cmake]

CMAKE_C_COMPILER = '/usr/bin/gcc'
CMAKE_CXX_COMPILER = 'C:\\user\\bin\\g++'
CMAKE_SOME_VARIABLE = ['some', 'value with spaces']
```

For instance, the `[cmake]` section from above will generate the following
code in the CMake toolchain file:

```cmake
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_C_COMPILER "C:/usr/bin/g++")
set(CMAKE_SOME_VARIABLE "some" "value with spaces")
```

### Project specific options

*New in 0.56.0*
Expand Down
8 changes: 8 additions & 0 deletions docs/markdown/snippets/cmake_cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## CMake subproject cross compilation support

Meson now supports cross compilation for CMake subprojects. Meson will try to
automatically guess most of the required CMake toolchain variables from existing
entries in the cross and native files. These variables will be stored in an
automatically generate CMake toolchain file in the build directory. The
remaining variables that can't be guessed can be added by the user in the
new `[cmake]` cross/native file section.
7 changes: 5 additions & 2 deletions mesonbuild/cmake/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
__all__ = [
'CMakeClient',
'CMakeExecutor',
'CMakeExecScope',
'CMakeException',
'CMakeFileAPI',
'CMakeInterpreter',
'CMakeTarget',
'CMakeToolchain',
'CMakeTraceLine',
'CMakeTraceParser',
'SingleTargetOptions',
Expand All @@ -31,10 +33,11 @@
'cmake_defines_to_args',
]

from .common import CMakeException, SingleTargetOptions, TargetOptions, cmake_defines_to_args
from .common import CMakeException, SingleTargetOptions, TargetOptions, cmake_defines_to_args, language_map
from .client import CMakeClient
from .executor import CMakeExecutor
from .fileapi import CMakeFileAPI
from .generator import parse_generator_expressions
from .interpreter import CMakeInterpreter, language_map
from .interpreter import CMakeInterpreter
from .toolchain import CMakeToolchain, CMakeExecScope
from .traceparser import CMakeTarget, CMakeTraceLine, CMakeTraceParser
14 changes: 5 additions & 9 deletions mesonbuild/cmake/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
# or an interpreter-based tool.

from .common import CMakeException, CMakeConfiguration, CMakeBuildFile
from .executor import CMakeExecutor
from ..mesonlib import MachineChoice
from .. import mlog
from contextlib import contextmanager
from subprocess import Popen, PIPE, TimeoutExpired
Expand All @@ -27,6 +25,7 @@

if T.TYPE_CHECKING:
from ..environment import Environment
from .executor import CMakeExecutor

CMAKE_SERVER_BEGIN_STR = '[== "CMake Server" ==['
CMAKE_SERVER_END_STR = ']== "CMake Server" ==]'
Expand Down Expand Up @@ -331,20 +330,17 @@ def resolve_reply_cmakeInputs(self, data: T.Dict[str, T.Any]) -> ReplyCMakeInput
return ReplyCMakeInputs(data['cookie'], Path(data['cmakeRootDirectory']), Path(data['sourceDirectory']), files)

@contextmanager
def connect(self) -> T.Generator[None, None, None]:
self.startup()
def connect(self, cmake_exe: 'CMakeExecutor') -> T.Generator[None, None, None]:
self.startup(cmake_exe)
try:
yield
finally:
self.shutdown()

def startup(self) -> None:
def startup(self, cmake_exe: 'CMakeExecutor') -> None:
if self.proc is not None:
raise CMakeException('The CMake server was already started')
for_machine = MachineChoice.HOST # TODO make parameter
cmake_exe = CMakeExecutor(self.env, '>=3.7', for_machine)
if not cmake_exe.found():
raise CMakeException('Unable to find CMake')
assert cmake_exe.found()

mlog.debug('Starting CMake server with CMake', mlog.bold(' '.join(cmake_exe.get_command())), 'version', mlog.cyan(cmake_exe.version()))
self.proc = Popen(cmake_exe.get_command() + ['-E', 'server', '--experimental', '--debug'], stdin=PIPE, stdout=PIPE)
Expand Down
12 changes: 12 additions & 0 deletions mesonbuild/cmake/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
from .._pathlib import Path
import typing as T

language_map = {
'c': 'C',
'cpp': 'CXX',
'cuda': 'CUDA',
'objc': 'OBJC',
'objcpp': 'OBJCXX',
'cs': 'CSharp',
'java': 'Java',
'fortran': 'Fortran',
'swift': 'Swift',
}

class CMakeException(MesonException):
pass

Expand Down
Loading

0 comments on commit 3372c58

Please sign in to comment.