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

[MesonToolchain] Binaries c, cpp and ld (added recently) can be lists #14676

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions conan/tools/meson/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ class MesonToolchain(object):
{% endfor %}

[binaries]
{% if c %}c = '{{c}}'{% endif %}
{% if cpp %}cpp = '{{cpp}}'{% endif %}
{% if c %}c = {{c}}{% endif %}
{% if cpp %}cpp = {{cpp}}{% endif %}
{% if ld %}ld = {{ld}}{% endif %}
{% if is_apple_system %}
{% if objc %}objc = '{{objc}}'{% endif %}
{% if objcpp %}objcpp = '{{objcpp}}'{% endif %}
Expand Down Expand Up @@ -190,13 +191,17 @@ def __init__(self, conanfile, backend=None):
self.c = compilers_by_conf.get("c") or build_env.get("CC") or default_comp
#: Defines the Meson ``cpp`` variable. Defaulted to ``CXX`` build environment value
self.cpp = compilers_by_conf.get("cpp") or build_env.get("CXX") or default_comp_cpp
#: Defines the Meson ``ld`` variable. Defaulted to ``LD`` build environment value
self.ld = build_env.get("LD")
# FIXME: Should we use the new tools.build:compiler_executables and avoid buildenv?
#: Defines the Meson ``c_ld`` variable. Defaulted to ``CC_LD`` or ``LD`` build
# Issue related: https://github.com/mesonbuild/meson/issues/6442
# PR related: https://github.com/mesonbuild/meson/pull/6457
#: Defines the Meson ``c_ld`` variable. Defaulted to ``CC_LD``
#: environment value
self.c_ld = build_env.get("CC_LD") or build_env.get("LD")
#: Defines the Meson ``cpp_ld`` variable. Defaulted to ``CXX_LD`` or ``LD`` build
self.c_ld = build_env.get("CC_LD")
#: Defines the Meson ``cpp_ld`` variable. Defaulted to ``CXX_LD``
#: environment value
self.cpp_ld = build_env.get("CXX_LD") or build_env.get("LD")
self.cpp_ld = build_env.get("CXX_LD")
#: Defines the Meson ``ar`` variable. Defaulted to ``AR`` build environment value
self.ar = build_env.get("AR")
#: Defines the Meson ``strip`` variable. Defaulted to ``STRIP`` build environment value
Expand Down Expand Up @@ -354,6 +359,12 @@ def _filter_list_empty_fields(v):
return list(filter(bool, v))

def _context(self):
def _sanitize_format(v):
if v is None or isinstance(v, list):
return v
ret = [x.strip() for x in v.split() if x]
return f"'{ret[0]}'" if len(ret) == 1 else ret

apple_flags = self.apple_isysroot_flag + self.apple_arch_flag + self.apple_min_version_flag
extra_flags = self._get_extra_flags()

Expand All @@ -380,11 +391,11 @@ def _context(self):
# https://mesonbuild.com/Machine-files.html#project-specific-options
"project_options": {k: to_meson_value(v) for k, v in self.project_options.items()},
# https://mesonbuild.com/Builtin-options.html#directories
# TODO : we don't manage paths like libdir here (yet?)
# https://mesonbuild.com/Machine-files.html#binaries
# https://mesonbuild.com/Reference-tables.html#compiler-and-linker-selection-variables
"c": self.c,
"cpp": self.cpp,
"c": _sanitize_format(self.c),
"cpp": _sanitize_format(self.cpp),
"ld": _sanitize_format(self.ld),
Copy link
Contributor

@jwillikers jwillikers Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@franramirez688 According to the Meson documentation here, I didn't think using a multivalue argument for the linker options made sense sense it would have to be one of gold, lld, bfd for Clang / GCC and only for MSVC / Clang-Cl should it be an executable. I think this is pretty different behavior than how autotools make use of the LD environment variable.

Fyi, I really appreciate you improving the interface for this stuff in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, indeed @jwillikers
I added that possibility only to be sure that I was not missing any corner case where you could want to pass several arguments to LD. Anyway, I hope consumers will use <>_ld instead, as Meson recommends in its documentation.

"objc": self.objc,
"objcpp": self.objcpp,
"c_ld": self.c_ld,
Expand Down

This file was deleted.

78 changes: 78 additions & 0 deletions conans/test/integration/toolchains/meson/test_mesontoolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest

from conan.tools.meson import MesonToolchain
from conans.test.assets.genconanfile import GenConanfile
from conans.test.utils.tools import TestClient


Expand Down Expand Up @@ -205,3 +206,80 @@ def test_clang_cl_vscrt(build_type, runtime, vscrt):
t.run("install . -pr:h=profile -pr:b=profile")
content = t.load(MesonToolchain.native_filename)
assert f"b_vscrt = '{vscrt}'" in content


def test_env_vars_from_build_require():
conanfile = textwrap.dedent("""
from conan import ConanFile
import os

class HelloConan(ConanFile):
name = 'hello_compiler'
version = '1.0'
def package_info(self):
self.buildenv_info.define("CC", "CC_VALUE")
self.buildenv_info.define("CC_LD", "CC_LD_VALUE")
self.buildenv_info.define("CXX", "CXX_VALUE")
self.buildenv_info.define("CXX_LD", "CXX_LD_VALUE")
self.buildenv_info.define("AR", "AR_VALUE")
self.buildenv_info.define("STRIP", "STRIP_VALUE")
self.buildenv_info.define("AS", "AS_VALUE")
self.buildenv_info.define("WINDRES", "WINDRES_VALUE")
self.buildenv_info.define("PKG_CONFIG", "PKG_CONFIG_VALUE")
self.buildenv_info.define("LD", "LD_VALUE")
""")
client = TestClient()
client.save({"conanfile.py": conanfile})
client.run("create .")

conanfile = textwrap.dedent("""
from conan import ConanFile
class HelloConan(ConanFile):
name = 'consumer'
version = '1.0'
generators = "MesonToolchain"
settings = "os", "arch", "compiler", "build_type"

def requirements(self):
self.tool_requires("hello_compiler/1.0", )
""")
# Now, let's check how all the build env variables are applied at consumer side
client.save({"conanfile.py": conanfile})
client.run("install . -pr:h=default -pr:b=default")
content = client.load("conan_meson_native.ini")
assert "c = 'CC_VALUE'" in content
assert "cpp = 'CXX_VALUE'" in content
assert "ld = 'LD_VALUE'" in content
assert "c_ld = 'CC_LD_VALUE'" in content
assert "cpp_ld = 'CXX_LD_VALUE'" in content
assert "ar = 'AR_VALUE'" in content
assert "strip = 'STRIP_VALUE'" in content
assert "as = 'AS_VALUE'" in content
assert "windres = 'WINDRES_VALUE'" in content
assert "pkgconfig = 'PKG_CONFIG_VALUE'" in content
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is coming from the test_meson_build_require. Previously, it was functional, but it shouldn't.



def test_check_c_cpp_ld_list_formats():
# Issue related: https://github.com/conan-io/conan/issues/14028
profile = textwrap.dedent("""
[settings]
os=Windows
arch=x86_64
compiler=gcc
compiler.version=9
compiler.cppstd=17
compiler.libcxx=libstdc++11
build_type=Release
[buildenv]
CC=aarch64-poky-linux-gcc -mcpu=cortex-a53 -march=armv8-a+crc+crypto
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So Meson needs this defined as a list for the c, cpp, etc? This reads a bit ugly imho, I'd expect to have the compiler as one thing and the list of flags as cxxflags or similar

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that, but the thing is that you can pass all those arguments to the CC in one shot as a list and it seems to be working as it's said in the issue #14028.

Overall, we're not changing the behavior at all. We agree that this should not be the way to go, but we're only allowing the users to have those compiler and compiler flags together without changing those env variables (up to them). You can check the Meson documentation too (https://mesonbuild.com/Machine-files.html#binaries).

Copy link
Contributor

@jwillikers jwillikers Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@memsharded This is unforunately how Yocto configures the CC and similar environment variables out-of-the-box.

CXX=aarch64-poky-linux-g++ -mcpu=cortex-a53 -march=armv8-a+crc+crypto
LD=aarch64-poky-linux-ld --sysroot=/opt/sysroots/cortexa53-crypto-poky-linux
""")
t = TestClient()
t.save({"conanfile.txt": "[generators]\nMesonToolchain",
"profile": profile})
t.run("install . -pr:h=profile -pr:b=profile")
content = t.load(MesonToolchain.native_filename)
assert "c = ['aarch64-poky-linux-gcc', '-mcpu=cortex-a53', '-march=armv8-a+crc+crypto']" in content
assert "cpp = ['aarch64-poky-linux-g++', '-mcpu=cortex-a53', '-march=armv8-a+crc+crypto']" in content
assert "ld = ['aarch64-poky-linux-ld', '--sysroot=/opt/sysroots/cortexa53-crypto-poky-linux']" in content