Repository: mesonbuild/meson

Issue:
target_compile_definitions from import cmake project not working correctly
I try to use this cmake library https://github.com/felixguendling/cista
In CmakeLists line: target_compile_definitions(cista INTERFACE CISTA_${CISTA_HASH}=1) passed to the compiler incorrectly.
On the cmake site https://cmake.org/cmake/help/latest/command/target_compile_definitions.html says that prefix -D not required, but meson doesn’t think so and pass to compiler two definitions at once: CISTA_FNV1A=1 -DCISTA_FNV1A=1 - ???
Change line to target_compile_definitions(cista INTERFACE -DCISTA_${CISTA_HASH}=1)
fix this problem.

But there is another library that does similar things and everything works fine:
target_compile_definitions(spdlog PUBLIC SPDLOG_COMPILED_LIB)
I think the problem is with INTERFACE or with parameter = 1


Discussion:
Same with:

https://github.com/juce-framework/JUCE/tree/juce6

E.g:

`JUCE/extras/Build/CMake/JUCEUtils.cmake(513):  target_compile_definitions(juce_analytics INTERFACE JUCE_MODULE_AVAILABLE_juce_analytics=1 )`

Ends up as:

`JUCE_MODULE_AVAILABLE_juce_analytics=1 LINUX=1 -DJUCE_MODULE_AVAILABLE_juce_analytics=1 -DJUCE_MODULE_AVAILABLE_juce_gui_basics=1 -DLINUX=1 `

in the Linker command line which breaks compilation.
Which meson and CMake version are you using? I am unable to reproduce this bug with meson 0.54.2 and CMake 3.17.3

It is generally recommended to use the latest meson and CMake version when using CMake subprojects. Can you also please both check if this issue is still present in the meson master and [0.54](https://github.com/mesonbuild/meson/tree/0.54) branch?

Resolving patch:
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -317,13 +317,6 @@ def postprocess(self, output_target_map: OutputTargetMap, root_src_dir: str, sub
         tgt = trace.targets.get(self.cmake_name)
         if tgt:
             self.depends_raw = trace.targets[self.cmake_name].depends
-            if self.type.upper() == 'INTERFACE_LIBRARY':
-                props = tgt.properties
-
-                self.includes += props.get('INTERFACE_INCLUDE_DIRECTORIES', [])
-                self.public_compile_opts += props.get('INTERFACE_COMPILE_DEFINITIONS', [])
-                self.public_compile_opts += props.get('INTERFACE_COMPILE_OPTIONS', [])
-                self.link_flags += props.get('INTERFACE_LINK_OPTIONS', [])
 
             # TODO refactor this copy paste from CMakeDependency for future releases
             reg_is_lib = re.compile(r'^(-l[a-zA-Z0-9_]+|-l?pthread)$')
@@ -342,6 +335,12 @@ def postprocess(self, output_target_map: OutputTargetMap, root_src_dir: str, sub
                 libraries = []
                 mlog.debug(tgt)
 
+                if 'INTERFACE_INCLUDE_DIRECTORIES' in tgt.properties:
+                    self.includes += [x for x in tgt.properties['INTERFACE_INCLUDE_DIRECTORIES'] if x]
+
+                if 'INTERFACE_LINK_OPTIONS' in tgt.properties:
+                    self.link_flags += [x for x in tgt.properties['INTERFACE_LINK_OPTIONS'] if x]
+
                 if 'INTERFACE_COMPILE_DEFINITIONS' in tgt.properties:
                     self.public_compile_opts += ['-D' + re.sub('^-D', '', x) for x in tgt.properties['INTERFACE_COMPILE_DEFINITIONS'] if x]
 


Test patch:
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt
--- a/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt	
+++ b/test cases/cmake/1 basic/subprojects/cmMod/CMakeLists.txt	
@@ -8,5 +8,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
 add_definitions("-DDO_NOTHING_JUST_A_FLAG=1")
 
 add_library(cmModLib++ SHARED cmMod.cpp)
+target_compile_definitions(cmModLib++ PRIVATE MESON_MAGIC_FLAG=21)
+target_compile_definitions(cmModLib++ INTERFACE MESON_MAGIC_FLAG=42)
 include(GenerateExportHeader)
 generate_export_header(cmModLib++)
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp
--- a/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp	
+++ b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.cpp	
@@ -2,6 +2,10 @@
 
 using namespace std;
 
+#if MESON_MAGIC_FLAG != 21
+#error "Invalid MESON_MAGIC_FLAG (private)"
+#endif
+
 cmModClass::cmModClass(string foo) {
   str = foo + " World";
 }
diff --git a/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp
--- a/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp	
+++ b/test cases/cmake/1 basic/subprojects/cmMod/cmMod.hpp	
@@ -3,6 +3,10 @@
 #include "cmmodlib++_export.h"
 #include <string>
 
+#if MESON_MAGIC_FLAG != 42 && MESON_MAGIC_FLAG != 21
+#error "Invalid MESON_MAGIC_FLAG"
+#endif
+
 class CMMODLIB___EXPORT cmModClass {
 private:
   std::string str;
diff --git a/test cases/cmake/10 header only/main.cpp b/test cases/cmake/10 header only/main.cpp
--- a/test cases/cmake/10 header only/main.cpp	
+++ b/test cases/cmake/10 header only/main.cpp	
@@ -3,8 +3,14 @@
 
 using namespace std;
 
+#define EXPECTED "Hello World compDef 42"
+
 int main(void) {
   cmModClass obj("Hello");
   cout << obj.getStr() << endl;
+  if (obj.getStr() != EXPECTED) {
+    cerr << "Expected: '" << EXPECTED << "'" << endl;
+    return 1;
+  }
   return 0;
 }
diff --git a/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt
--- a/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt	
+++ b/test cases/cmake/10 header only/subprojects/cmMod/CMakeLists.txt	
@@ -9,3 +9,4 @@ add_library(cmModLib INTERFACE)
 set_target_properties(cmModLib PROPERTIES INTERFACE_COMPILE_OPTIONS "-DCMAKE_FLAG_MUST_BE_PRESENT")
 target_include_directories(cmModLib INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include")
 target_compile_definitions(cmModLib INTERFACE -DCMAKE_COMPILER_DEFINE_STR="compDef")
+target_compile_definitions(cmModLib INTERFACE MESON_MAGIC_FLAG=42)
diff --git a/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp b/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp
--- a/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp	
+++ b/test cases/cmake/10 header only/subprojects/cmMod/include/cmMod.hpp	
@@ -6,6 +6,9 @@
 #error "The flag CMAKE_FLAG_MUST_BE_PRESENT was not set"
 #endif
 
+#define xstr(s) str(s)
+#define str(s) #s
+
 class cmModClass {
   private:
     std::string str;
@@ -13,6 +16,8 @@ class cmModClass {
     cmModClass(std::string foo) {
       str = foo + " World ";
       str += CMAKE_COMPILER_DEFINE_STR;
+      str += ' ';
+      str += xstr(MESON_MAGIC_FLAG);
     }
 
     inline std::string getStr() const { return str; }