Platform notes

This page collects information that is specific to a platform or to a toolchain.

macOS deployment target

Programs can be compiled for older macOS versions than the one they are compiled on. The version of the build machine therefore does not tell which functions are available when the program runs.

The deployment target is chosen by the compiler. Either set the MACOSX_DEPLOYMENT_TARGET environment variable before running Meson, or pass -mmacosx-version-min in both the compile and the link arguments, for example in a native file:

[built-in options]
c_args = ['-mmacosx-version-min=10.11']
c_link_args = ['-mmacosx-version-min=10.11']

The checks that Meson runs use the same arguments, so they see the deployment target.

When detecting a function with compiler.has_function(), specify the header that declares it in the prefix argument. For example, open_memstream was introduced in macOS 10.13. When building on macOS 10.13 for macOS 10.11, the following check correctly reports the function as missing:

cc.has_function('open_memstream', prefix : '#include <stdio.h>')

Without the header, the check lacks the availability information and incorrectly reports the function as available.

AIX and IBM i

Meson supports AIX with the GCC and OpenXL compilers. IBM i is supported in the PASE environment, which uses the AIX user space. On both, host_machine.system() returns 'aix'. host_machine.kernel() returns 'aix' or 'os400' to tell them apart.

The AIX linker always links the whole contents of static libraries, so link_with is accepted but has the same effect as link_whole.

Windows

MinGW, UCRT and MSVC

On Windows, Meson uses the compiler that it finds first in the environment, so the shell used to run Meson selects the toolchain. With MSYS2, this is the environment that was started (MINGW64, UCRT64, CLANG64, and so on).

  • MINGW64 links to the old msvcrt.dll C runtime.
  • UCRT64 and CLANG64 link to the Universal C Runtime (UCRT), which is the runtime used by current versions of MSVC.
  • MSVC and clang-cl link to the UCRT as well, and b_vscrt selects between the dynamic (/MD) and the static (/MT) version.

Libraries built with MinGW and with MSVC can be mixed as long as they use the same C runtime, for example UCRT64 with MSVC. Mixing runtimes is likely to cause crashes, because each runtime has its own heap and file descriptor table.

The two toolchains differ in how they name and export libraries. See Library file names for the names, and the FAQ for the exported symbols.

Search path for DLLs

Windows has no equivalent of an rpath or of LD_LIBRARY_PATH. A program finds its DLLs in its own directory and in the directories listed in PATH. When Meson runs a program from the build tree, it adds to PATH the directories of the DLLs that the program needs. This applies to:

  • tests and benchmarks, including the programs and targets listed in their depends;
  • meson devenv, for the executables of the project;
  • custom targets and generators that run an executable from the build tree.

The directories are:

  • the directories of the shared_library() targets that the program links to, directly or transitively. The output of a custom_target() is not included, even if it is a DLL;
  • the directories of DLLs that the program links to outside the build tree, for example when they are found with find_library();
  • when cross compiling with MinGW, the bin directory of the toolchain and of the sys_root and root of the cross file, and the program and library directories of the compilers.

Wine

When running Windows executables on another operating system, PATH is not used to find DLLs. Meson sets WINEPATH with the same directories in meson devenv, when the host machine is Windows and the build machine is not. meson test does the same for tests whose command is wine, for example through an exe_wrapper. The directories of the executables are added as well, so that wine foo.exe works.

Wine limits the size of WINEPATH to 1024 bytes. Meson shortens the paths if necessary, using paths relative to the working directory and Windows short names, and prints a warning if the result is still too long.

Emscripten

Meson can use emcc and em++ from Emscripten 1.39.19 or newer to build WebAssembly. They can only be used for cross compilation. A minimal cross file is:

[binaries]
c = 'emcc'
cpp = 'em++'
ar = 'emar'

[host_machine]
system = 'emscripten'
cpu_family = 'wasm32'
cpu = 'wasm32'
endian = 'little'

The following behavior is specific to Emscripten:

  • Executables have the .js suffix. If a .wasm file is produced next to it, meson install installs it as well.
  • The linker is detected as ld.wasm, the name that Meson uses for wasm-ld.
  • The c_thread_count and cpp_thread_count options set -sPTHREAD_POOL_SIZE when a target uses threads. The default is 4, and 0 does not pass the option.
  • compiler.find_library() can look up JavaScript libraries. The name must end with .js, and either be an absolute path or be searched in the directories passed with dirs.
glue_lib = cc.find_library('gluefuncs.js', dirs: meson.current_source_dir())
executable('prog', 'prog.c', dependencies: glue_lib)

Running the output requires exe_wrapper, for example node. See running target programs.

QNX

Meson can detect and use qcc and q++, the C and C++ compiler drivers shipped with the QNX Software Development Platform (SDP). For cross compilation, point the [binaries] section of the cross file at qcc and q++, including the required -V target selector, and set system = 'qnx' in [host_machine]:

[binaries]
c = ['qcc', '-Vgcc_ntoaarch64le']
cpp = ['q++', '-Vgcc_ntoaarch64le']

[host_machine]
system = 'qnx'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'

The following limitations apply:

  1. ThinLTO incremental cache does not work. -Db_thinlto_cache=true raises an error at configure time, while -Db_lto=true is unaffected.
  2. Alternate linker selection is not supported. Setting c_ld or cpp_ld (for example to lld or gold) raises an error.
  3. If a header is deleted, stale entries remain in the dependency files, because -MP does not emit phony header rules. A clean build is needed to recover.
  4. There is no static sanitizer runtime, so -static-libasan is rejected and only the shared runtime can be linked.
  5. The available sanitizers depend on the SDP version. SDP 7.1 only provides libubsan, so -Db_sanitize=address and -Db_sanitize=leak fail to link there. SDP 8.0 adds asan and lsan. -Db_sanitize=undefined works on both, and tsan is not available on either.
  6. C++20 named modules do not work. With SDP 8.0, -fmodules-ts compiles but silently ignores .cppm and .ixx files. With SDP 7.1, -fmodules-ts is rejected for C++ sources. Plain -fmodules is rejected on both. This only affects projects that enable modules through cpp_args.
  7. Relinking is avoided for unchanged shared libraries only on native QNX builds. When cross compiling to QNX, shared libraries are always relinked.

The results of the search are