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

BugFix: MesonToolchain does not pick up CC/CXX from build requirements (in build profile) #8362

Closed
wants to merge 3 commits into from
Closed
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
31 changes: 19 additions & 12 deletions conan/tools/meson/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@ class MesonToolchain(object):
{% if pkgconfig %}pkgconfig = {{pkgconfig}}{% endif %}

[built-in options]
preprocessor_definitions = [{% for it, value in preprocessor_definitions.items() -%}
'-D{{ it }}="{{ value}}"'{%- if not loop.last %}, {% endif %}{% endfor %}]
{% if buildtype %}buildtype = {{buildtype}}{% endif %}
{% if debug %}debug = {{debug}}{% endif %}
{% if default_library %}default_library = {{default_library}}{% endif %}
{% if b_vscrt %}b_vscrt = {{b_vscrt}}{% endif %}
{% if b_ndebug %}b_ndebug = {{b_ndebug}}{% endif %}
{% if b_staticpic %}b_staticpic = {{b_staticpic}}{% endif %}
{% if cpp_std %}cpp_std = {{cpp_std}}{% endif %}
{% if c_args %}c_args = {{c_args}}{% endif %}
{% if c_link_args %}c_link_args = {{c_link_args}}{% endif %}
{% if cpp_args %}cpp_args = {{cpp_args}}{% endif %}
{% if cpp_link_args %}cpp_link_args = {{cpp_link_args}}{% endif %}
c_args = {{c_args}} + preprocessor_definitions
c_link_args = {{c_link_args}}
cpp_args = {{cpp_args}} + preprocessor_definitions
cpp_link_args = {{cpp_link_args}}
{% if pkg_config_path %}pkg_config_path = {{pkg_config_path}}{% endif %}
""")

Expand Down Expand Up @@ -71,7 +73,9 @@ def __init__(self, conanfile, env=os.environ):
self._shared = self._conanfile.options.get_safe("shared")
self._fpic = self._conanfile.options.get_safe("fPIC")
self.definitions = dict()
self._env = env
self.preprocessor_definitions = dict()
self._env = env.copy()
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to wait until we have the new env management there: #8534, because partially providing it, then breaking could be probably more annoying that having to wait.

self._env.update(self._conanfile.env)

@staticmethod
def _to_meson_value(value):
Expand Down Expand Up @@ -137,6 +141,10 @@ def _to_meson_cppstd(self, cppstd):
def _none_if_empty(value):
return "'%s'" % value if value.strip() else None

def _env_array(self, name):
import shlex
return shlex.split(self._env.get(name, ''))

@property
def _context(self):
project_options = []
Expand Down Expand Up @@ -171,13 +179,12 @@ def _context(self):
"b_ndebug": self._to_meson_value(self._ndebug) if self._build_type else None,
# https://mesonbuild.com/Builtin-options.html#compiler-options
"cpp_std": self._to_meson_cppstd(self._cppstd) if self._cppstd else None,
"c_args": self._none_if_empty(self._env.get("CPPFLAGS", '') +
self._env.get("CFLAGS", '')),
"c_link_args": self._env.get("LDFLAGS", None),
"cpp_args": self._none_if_empty(self._env.get("CPPFLAGS", '') +
self._env.get("CXXFLAGS", '')),
"cpp_link_args": self._env.get("LDFLAGS", None),
"pkg_config_path": "'%s'" % os.getcwd()
"c_args": self._to_meson_value(self._env_array('CPPFLAGS') + self._env_array('CFLAGS')),
"c_link_args": self._to_meson_value(self._env_array('LDFLAGS')),
"cpp_args": self._to_meson_value(self._env_array('CPPFLAGS') + self._env_array('CXXFLAGS')),
"cpp_link_args": self._to_meson_value(self._env_array('LDFLAGS')),
"pkg_config_path": "'%s'" % os.getcwd(),
"preprocessor_definitions": self.preprocessor_definitions
}
return context

Expand Down
4 changes: 3 additions & 1 deletion conans/test/functional/toolchains/meson/test_android.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ def env(self):
ar = self._tool('ar')
cflags = '--target=%s' % self._target
cxxflags = '--target=%s' % self._target
ldflags = '--target=%s' % self._target

return {'CC': cc,
'CXX': cxx,
'AR': ar,
'CFLAGS': cflags,
'CXXFLAGS': cxxflags}
'CXXFLAGS': cxxflags,
'LDFLAGS': ldflags}

def profile(self):
template = textwrap.dedent("""
Expand Down
72 changes: 72 additions & 0 deletions conans/test/functional/toolchains/meson/test_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os
import textwrap

from conans.test.assets.sources import gen_function_cpp, gen_function_h
from conans.test.functional.toolchains.meson._base import TestMesonBase


class MesonToolchainTest(TestMesonBase):

_conanfile_br = textwrap.dedent("""
from conans import ConanFile


class BuildRequires(ConanFile):

def package_info(self):
self.env_info.CC = "custom C compiler"
self.env_info.CXX = "custom CXX compiler"
""")

_conanfile_py = textwrap.dedent("""
from conans import ConanFile, tools
from conan.tools.meson import Meson, MesonToolchain


class App(ConanFile):
settings = "os", "arch", "compiler", "build_type"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}
build_requires = ("br/1.0@",)
generators = ("virtualenv",)

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def generate(self):
tc = MesonToolchain(self)
tc.generate()

def build(self):
meson = Meson(self)
meson.configure()
meson.build()
""")

_meson_build = textwrap.dedent("""
project('tutorial', 'cpp')
hello = library('hello', 'hello.cpp')
executable('demo', 'main.cpp', link_with: hello)
""")

def test_build(self):
self.t.save({"conanfile.py": self._conanfile_br})
self.t.run("create . br/1.0@")

hello_h = gen_function_h(name="hello")
hello_cpp = gen_function_cpp(name="hello")
app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])

self.t.save({"conanfile.py": self._conanfile_py,
"meson.build": self._meson_build,
"hello.h": hello_h,
"hello.cpp": hello_cpp,
"main.cpp": app}, clean_first=True)

self.t.run("install . %s" % self._settings_str)

content = self.t.load("conan_meson_native.ini")

self.assertIn("c = 'custom C compiler", content)
self.assertIn("cpp = 'custom CXX compiler", content)
4 changes: 3 additions & 1 deletion conans/test/functional/toolchains/meson/test_ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,13 @@ def env(self):
cflags += " -isysroot " + self.xcrun.sdk_path
cflags += " -arch " + to_apple_arch(self.arch)
cxxflags = cflags
ldflags = cflags

return {'CC': cc,
'CXX': cxx,
'CFLAGS': cflags,
'CXXFLAGS': cxxflags}
'CXXFLAGS': cxxflags,
'LDFLAGS': ldflags}

def profile(self):
template = textwrap.dedent("""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import os
import textwrap

from conans.test.assets.sources import gen_function_cpp, gen_function_h
from conans.test.functional.toolchains.meson._base import TestMesonBase


class MesonPreprocessorDefinitionsTest(TestMesonBase):
_conanfile_py = textwrap.dedent("""
from conans import ConanFile, tools
from conan.tools.meson import Meson, MesonToolchain


class App(ConanFile):
settings = "os", "arch", "compiler", "build_type"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def generate(self):
tc = MesonToolchain(self)
tc.preprocessor_definitions["TEST_DEFINITION1"] = "TestPpdValue1"
tc.preprocessor_definitions["TEST_DEFINITION2"] = "TestPpdValue2"
tc.generate()

def build(self):
meson = Meson(self)
meson.configure()
meson.build()
""")

_meson_build = textwrap.dedent("""
project('tutorial', 'cpp')
hello = library('hello', 'hello.cpp')
executable('demo', 'main.cpp', link_with: hello)
""")

def test_build(self):
hello_h = gen_function_h(name="hello")
hello_cpp = gen_function_cpp(name="hello",
preprocessor=["TEST_DEFINITION1", "TEST_DEFINITION2"])
app = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])

self.t.save({"conanfile.py": self._conanfile_py,
"meson.build": self._meson_build,
"hello.h": hello_h,
"hello.cpp": hello_cpp,
"main.cpp": app})

self.t.run("install . %s" % self._settings_str)

content = self.t.load("conan_meson_native.ini")

self.assertIn("[built-in options]", content)
self.assertIn("buildtype = 'release'", content)

self.t.run("build .")
self.t.run_command(os.path.join("build", "demo"))

self.assertIn("hello: Release!", self.t.out)
self.assertIn("TEST_DEFINITION1: TestPpdValue1", self.t.out)
self.assertIn("TEST_DEFINITION2: TestPpdValue2", self.t.out)

self._check_binary()