Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meson lacks support for cross compilation #1222

Open
allsey87 opened this issue Jul 8, 2024 · 5 comments
Open

Meson lacks support for cross compilation #1222

allsey87 opened this issue Jul 8, 2024 · 5 comments

Comments

@allsey87
Copy link
Contributor

allsey87 commented Jul 8, 2024

Meson support was merged in #986, but appears to not have support for cross compilation. I am concluding this from a use case where I am trying to cross compile using the Emscripten compiler. For this to work, a cross file should be provided to meson setup, however there is no logic for passing cross file as can be seen here:

https://github.com/bazelbuild/rules_foreign_cc/blob/9d5727d5e51bf1be8423dff7996bdb4d847b47e6/foreign_cc/meson.bzl#L113-L119

I think this should be solved by generating a cross file for Meson mirroring what is done for the CMake toolchain file here:

https://github.com/bazelbuild/rules_foreign_cc/blob/9d5727d5e51bf1be8423dff7996bdb4d847b47e6/foreign_cc/private/cmake_script.bzl#L197-L230

What do you think @jheaff1, @jsharpe, and @edison-moreland?

@jsharpe
Copy link
Member

jsharpe commented Jul 8, 2024

Very happy to accept a PR that adds support for cross-compilation for meson.

@allsey87
Copy link
Contributor Author

allsey87 commented Jul 8, 2024

If we can move quickly, I can look into that but let's start with #1223

@bbatliner-ocient
Copy link

bbatliner-ocient commented Aug 14, 2024

Chiming in with the bare minimum cross-compilation support that appeared to work for me:

diff --git a/foreign_cc/meson.bzl b/foreign_cc/meson.bzl
index 9d4179a..ea25bf2 100644
--- a/foreign_cc/meson.bzl
+++ b/foreign_cc/meson.bzl
@@ -68,8 +68,17 @@ def _create_meson_script(configureParameters):
     inputs = configureParameters.inputs
 
     tools = get_tools_info(ctx)
+    flags = get_flags_info(ctx)
     script = pkgconfig_script(inputs.ext_build_dirs)
 
+    # write cross file
+    script.append("cat > crosstool_bazel.txt << EOF")
+    script.append("[binaries]")
+    script.append("c = '{}'".format(_absolutize(ctx.workspace_name, tools.cc)))
+    script.append("cpp = '{}'".format(_absolutize(ctx.workspace_name, tools.cxx)))
+    script.append("EOF")
+    script.append("")
+
     # CFLAGS and CXXFLAGS are also set in foreign_cc/private/cmake_script.bzl, so that meson
     # can use the intended tools.
     # However, they are split by meson on whitespace. For Windows it's common to have spaces in path
@@ -91,7 +100,6 @@ def _create_meson_script(configureParameters):
     if cxxopts:
         script.append("##export_var## CXXFLAGS \"{} ${{CXXFLAGS:-}}\"".format(" ".join(cxxopts).replace("\"", "'")))
 
-    flags = get_flags_info(ctx)
     if flags.cxx_linker_executable:
         script.append("##export_var## LDFLAGS \"{} ${{LDFLAGS:-}}\"".format(" ".join(flags.cxx_linker_executable).replace("\"", "'")))
 
@@ -112,7 +120,7 @@ def _create_meson_script(configureParameters):
 
     setup_args_str = " ".join(expand_locations_and_make_variables(ctx, ctx.attr.setup_args, "setup_args", data))
 
-    script.append("{prefix}{meson} setup --prefix={install_dir} {setup_args} {options} {source_dir}".format(
+    script.append("{prefix}{meson} setup --cross-file crosstool_bazel.txt --prefix={install_dir} {setup_args} {options} {source_dir}".format(
         prefix = prefix,
         meson = attrs.meson_path,
         install_dir = "$$INSTALLDIR$$",

Unconditionally writing this file and passing --cross-file with either a native c and cpp binary, or a cross-compiling c and cpp binary, appeared to be everything Meson needed to build with various --platforms.

I recognize that this has some ways to go before claiming support, but wanted to get discussion going.

  • A generate_crosstool_file attr of the meson rule similar to cmake attr, to conditionally enable this
  • I could not understand the rationale of if " " not in tools.cc: and conditionally exporting CC and CXX, presumably only for Windows. Is this fixed upstream in Meson? shlex.split eats up backslashes on Windows mesonbuild/meson#5726 If this is still an issue, then it would seem that we can't always write tools.cc and tools.cxx into the cross file, if Meson on Windows is going to parse their paths weirdly.
  • Are none of the other options supported by Meson cross files required? This feels too simple.

Following up, that patch worked for me to compile one library, but failed on a different library. It's evidently not a complete solution.

@allsey87
Copy link
Contributor Author

allsey87 commented Aug 15, 2024

I am using Meson for cross compilation to WebAssembly via Emscripten and it seems to work pretty well for most things now. I am just passing a hardcoded --cross-file via setup_args for the moment which I took from the NumPy project:

[binaries]
exe_wrapper = 'node' # run webassembly inside of node
pkg-config = 'pkg-config'

[properties]
needs_exe_wrapper = true
skip_sanity_check = true
longdouble_format = 'IEEE_QUAD_LE' # for numpy

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

Notably, I do not set c or cpp under binaries. I am using platforms and a custom toolchain which I believe sets the CC and CXX environment variables which Meson picks up automatically.

Disclaimer: I have only been using Bazel for a couple months

@mering
Copy link

mering commented Oct 16, 2024

@bbatliner-ocient you might want to include the ar and strip tools in your patch.

For ar you can use:

script.append("ar = '{}'".format(_absolutize(ctx.workspace_name, tools.cxx_linker_static)))

For strip one actually has to add the following into CxxToolsInfo in cc_toolchain_util.bzl:

strip = cc_common.get_tool_for_action(
    feature_configuration = feature_configuration,
    action_name = ACTION_NAMES.strip,
),

Note: meson also support using the same file as --native-file, so it might be acceptable to always generate this file and just change the flag how this file is passed to meson.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants