Repository: conan-io/conan

Issue:
[bug] MesonToolchain ignores tools.build:defines   ... and tc.preprocess_definitions quote problems
### Describe the bug

Windows, MSVC, conan 2.2.3

I'm building a project with MSVC and Debug mode.
I want to set _ITERATOR_DEBUG_LEVEL=0 across ALL dependencies.  This is required for linking.

I added to the profile:
```
[conf]
tools.build:defines=["_ITERATOR_DEBUG_LEVEL=0"]
```

harfbuzz is a problem.  It is a Meson recipe, and it appears Meson ignores tools.build:defines
I am not sure why, it has `tc.preprocessor_definitions` just like the CMakeToolchain, why would conan not pass these onto Meson as well?

Additionally, I tried to test by adjusting harfbuzz's recipe, by adding to `def configure(self):`
`tc.preprocessor_definitions["_ITERATOR_DEBUG_LEVEL"] = 0`

But Meson then builds with this command line (which fails with a cl.exe fatal error):
```
"cl" "-Isrc\libharfbuzz.a.p" "-Isrc" "-I..\src\src" "-I." "-I..\src" "-IM:/cocache4/cache/b/freet0508e9d7e6575/p/include" "-IM:/cocache4/cache/b/freet0508e9d7e6575/p/include/freetype2" "-IM:/cocache4/cache/b/libpn2b1716cb8fc8a/p/include" "-IM:/cocache4/cache/b/brotla8ae8b1cc3ea9/p/include" "-IM:/cocache4/cache/b/brotla8ae8b1cc3ea9/p/include/brotli" "-IM:/cocache4/cache/b/zlibaa051031a3f1a/p/include" "-IM:/cocache4/cache/b/bzip21d1b3a8fb9846/p/include" "-IM:/cocache4/cache/b/glib797de4fd80358/p/include" "-IM:/cocache4/cache/b/glib797de4fd80358/p/include/glib-2.0" "-IM:/cocache4/cache/b/glib797de4fd80358/p/lib/glib-2.0/include" "-IM:/cocache4/cache/b/pcre2002bf79de5d67/p/include" "-IM:/cocache4/cache/b/libgee81b73e14585e/p/include" "-IM:/cocache4/cache/b/libic07bd529a5ac88/p/include" "/MDd" "/nologo" "/showIncludes" "/utf-8" "/Zc:__cplusplus" "/W2" "/EHs-c-" "/std:c++20" "/Od" "/Zi" "/wd4244" "/utf-8" "-DHAVE_CONFIG_H" "-D_ITERATOR_DEBUG_LEVEL=\"0\"" "-DPCRE2_STATIC" "/Fdsrc\libharfbuzz.a.p\hb-ot-map.cc.pdb" /Fosrc/libharfbuzz.a.p/hb-ot-map.cc.obj "/c" ../src/src/hb-ot-map.cc
```

Note this command line parameter: `"-D_ITERATOR_DEBUG_LEVEL=\"0\""`
It should simply read: `"-D_ITERATOR_DEBUG_LEVEL=0"`

I can't even hack the recipe to get where I need to go ...



Discussion:
It appears to work if I add to the profile:
```
tools.build:cflags=["-D_ITERATOR_DEBUG_LEVEL=0"]
tools.build:cxxflags=["-D_ITERATOR_DEBUG_LEVEL=0"]
```
Why aren't tools.build:defines supported for MesonToolchain?

Hi @paulharris 

You're right, thanks a lot for reporting 👍 Working on fixing this.



Patch:
diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py
index 3cd4ce73bfc..80f13338750 100644
--- a/conan/tools/meson/toolchain.py
+++ b/conan/tools/meson/toolchain.py
@@ -352,10 +352,12 @@ def _get_extra_flags(self):
         exelinkflags = self._conanfile.conf.get("tools.build:exelinkflags", default=[], check_type=list)
         linker_scripts = self._conanfile.conf.get("tools.build:linker_scripts", default=[], check_type=list)
         linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts]
+        defines = [f"-D{d}" for d in self._conanfile.conf.get("tools.build:defines", default=[], check_type=list)]
         return {
             "cxxflags": cxxflags,
             "cflags": cflags,
-            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags
+            "ldflags": sharedlinkflags + exelinkflags + linker_script_flags,
+            "defines": defines
         }
 
     @staticmethod
@@ -377,13 +379,13 @@ def _sanitize_format(v):
         apple_flags = self.apple_isysroot_flag + self.apple_arch_flag + self.apple_min_version_flag
         extra_flags = self._get_extra_flags()
 
-        self.c_args.extend(apple_flags + extra_flags["cflags"])
-        self.cpp_args.extend(apple_flags + extra_flags["cxxflags"])
+        self.c_args.extend(apple_flags + extra_flags["cflags"] + extra_flags["defines"])
+        self.cpp_args.extend(apple_flags + extra_flags["cxxflags"] + extra_flags["defines"])
         self.c_link_args.extend(apple_flags + extra_flags["ldflags"])
         self.cpp_link_args.extend(apple_flags + extra_flags["ldflags"])
         # Objective C/C++
-        self.objc_args.extend(self.c_args)
-        self.objcpp_args.extend(self.cpp_args)
+        self.objc_args.extend(self.c_args + extra_flags["defines"])
+        self.objcpp_args.extend(self.cpp_args + extra_flags["defines"])
         # These link_args have already the LDFLAGS env value so let's add only the new possible ones
         self.objc_link_args.extend(apple_flags + extra_flags["ldflags"])
         self.objcpp_link_args.extend(apple_flags + extra_flags["ldflags"])


Test patch:
diff --git a/conans/test/integration/toolchains/meson/test_mesontoolchain.py b/conans/test/integration/toolchains/meson/test_mesontoolchain.py
index a79b9bed160..740cb931de7 100644
--- a/conans/test/integration/toolchains/meson/test_mesontoolchain.py
+++ b/conans/test/integration/toolchains/meson/test_mesontoolchain.py
@@ -87,6 +87,8 @@ def test_extra_flags_via_conf():
         tools.build:cflags=["-flag3", "-flag4"]
         tools.build:sharedlinkflags+=["-flag5"]
         tools.build:exelinkflags+=["-flag6"]
+        # Issue related: https://github.com/conan-io/conan/issues/16169
+        tools.build:defines=["define1=0"]
    """)
     t = TestClient()
     t.save({"conanfile.txt": "[generators]\nMesonToolchain",
@@ -94,8 +96,8 @@ def test_extra_flags_via_conf():
 
     t.run("install . -pr:h=profile -pr:b=profile")
     content = t.load(MesonToolchain.native_filename)
-    assert "cpp_args = ['-flag0', '-other=val', '-flag1', '-flag2', '-D_GLIBCXX_USE_CXX11_ABI=0']" in content
-    assert "c_args = ['-flag0', '-other=val', '-flag3', '-flag4']" in content
+    assert "cpp_args = ['-flag0', '-other=val', '-flag1', '-flag2', '-Ddefine1=0', '-D_GLIBCXX_USE_CXX11_ABI=0']" in content
+    assert "c_args = ['-flag0', '-other=val', '-flag3', '-flag4', '-Ddefine1=0']" in content
     assert "c_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content
     assert "cpp_link_args = ['-flag0', '-other=val', '-flag5', '-flag6']" in content