Repository: mesonbuild/meson

Issue:
Cmake subproject target names - filenames
**Describe the bug**
When using a Cmake subproject target names are prefixed with cm_ for namespacing. This in itself is fine, however the target names are then also used as the executable and library sonames, which results in mangled names that are not installable. These also do not match with pkg-config files generated by the Cmake build.

**To Reproduce**
Subproject a Cmake project, compile it and see that it's executable and library filenamea/sonames are overriden

**Expected behavior**
Filenames and sonames as they would've been when using Cmake directly.

**system parameters**
Meson 0.58.1, Ubuntu 21.04

A workable workaround (for me) could also be to be able to override the file/soname on a specific Cmake target.



Discussion:
> which results in mangled names that are not installable

Do you have an example project for this? The libraries should still install and be usable by your Meson project. What exactly is your use-case here?

Also, if you want to install a CMake project system-wide, so that it can be used/found by other projects, you really should install the CMake project directly. There are additional issues with installing CMake subprojects, since we do not really track the `install()` function (just some stuff CMake tells us in their introspection data) so the install *will* be incomplete.

So, I would classify this as not a bug but working as intended if your project works after an install with the CMake subproject.
The project I'm trying to build as a subproject is haivision/srt, it has an srt_static target that I'd expect to be output as libsrt.a but instead becomes cm_srt_static.a.

My usecase is building a golang application via a custom target that links against it. Unfortunately the golang linking target is declared in the .go files via cgo directives, so it needs to preserve the name for linking correctly.

Since I build a static library I have a hacked workaround that uses CP as a custom target to produce the expected filename.
But it would be nice if there would be a better solution.

I'm fully aware that my usecase is not supported btw ;)
That seems like a somewhat valid use case I guess... Specifying a (possibly empty) prefix shouldn't hurt.

Resolving patch:
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -26,6 +26,7 @@
 from ..mesondata import mesondata
 from ..compilers.compilers import assembler_suffixes, lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
 from ..programs import ExternalProgram
+from ..coredata import FORBIDDEN_TARGET_NAMES
 from enum import Enum
 from functools import lru_cache
 from pathlib import Path
@@ -120,7 +121,9 @@
 _cmake_name_regex = re.compile(r'[^_a-zA-Z0-9]')
 def _sanitize_cmake_name(name: str) -> str:
     name = _cmake_name_regex.sub('_', name)
-    return 'cm_' + name
+    if name in FORBIDDEN_TARGET_NAMES or name.startswith('meson'):
+        name = 'cm_' + name
+    return name
 
 class OutputTargetMap:
     rm_so_version = re.compile(r'(\.[0-9]+)+$')


Test patch:
diff --git a/test cases/cmake/19 advanced options/test.json b/test cases/cmake/19 advanced options/test.json
--- a/test cases/cmake/19 advanced options/test.json	
+++ b/test cases/cmake/19 advanced options/test.json	
@@ -1,6 +1,6 @@
 {
   "installed": [
-    {"type": "exe", "file": "usr/bin/cm_testEXE"}
+    {"type": "exe", "file": "usr/bin/testEXE"}
   ],
   "tools": {
     "cmake": ">=3.11"
diff --git a/test cases/cmake/2 advanced/meson.build b/test cases/cmake/2 advanced/meson.build
--- a/test cases/cmake/2 advanced/meson.build	
+++ b/test cases/cmake/2 advanced/meson.build	
@@ -21,3 +21,7 @@ test('test2', exe2)
 # Test if we can also extract executables
 assert(sub_pro.target_type('testEXE') == 'executable', 'The type must be executable for obvious reasons')
 test('test3', sub_pro.target('testEXE'))
+
+# Test that we can add a new target with the same name as the CMake subproject
+exe4 = executable('testEXE', ['main.cpp'], dependencies: [sub_sta])
+test('test4', exe4)
diff --git a/test cases/cmake/2 advanced/test.json b/test cases/cmake/2 advanced/test.json
--- a/test cases/cmake/2 advanced/test.json	
+++ b/test cases/cmake/2 advanced/test.json	
@@ -1,6 +1,6 @@
 {
   "installed": [
-    {"type": "exe", "file": "usr/bin/cm_testEXE"}
+    {"type": "exe", "file": "usr/bin/testEXE"}
   ],
   "tools": {
     "cmake": ">=3.11"
diff --git a/test cases/cmake/3 advanced no dep/meson.build b/test cases/cmake/3 advanced no dep/meson.build
--- a/test cases/cmake/3 advanced no dep/meson.build	
+++ b/test cases/cmake/3 advanced no dep/meson.build	
@@ -14,5 +14,6 @@ test('test1', exe1)
 test('test2', exe2)
 
 # Test if we can also extract executables
-assert(sub_pro.target_type('testEXE') == 'executable', 'The type must be executable for obvious reasons')
-test('test3', sub_pro.target('testEXE'))
+assert(sub_pro.target_type('meson-testEXE') == 'executable', 'The type must be executable for obvious reasons')
+test('test3', sub_pro.target('meson-testEXE'))
+test('test4', sub_pro.target('benchmark'))
diff --git a/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt
--- a/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt	
+++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt	
@@ -15,12 +15,12 @@ generate_export_header(cmModLib)
 
 set_target_properties(cmModLib PROPERTIES VERSION 1.0.1)
 
-add_executable(testEXE main.cpp)
-add_executable(testEXE2 main.cpp)
+add_executable(meson-testEXE main.cpp)
+add_executable(benchmark main.cpp)
 
-target_link_libraries(testEXE cmModLib)
-target_link_libraries(testEXE2 cmModLib)
+target_link_libraries(meson-testEXE cmModLib)
+target_link_libraries(benchmark cmModLib)
 
 target_compile_definitions(cmModLibStatic PUBLIC CMMODLIB_STATIC_DEFINE)
 
-install(TARGETS testEXE testEXE2 LIBRARY DESTINATION lib RUNTIME DESTINATION bin)
+install(TARGETS meson-testEXE benchmark LIBRARY DESTINATION lib RUNTIME DESTINATION bin)
diff --git a/test cases/cmake/3 advanced no dep/test.json b/test cases/cmake/3 advanced no dep/test.json
--- a/test cases/cmake/3 advanced no dep/test.json	
+++ b/test cases/cmake/3 advanced no dep/test.json	
@@ -1,9 +1,9 @@
 {
   "installed": [
-    {"type": "pdb", "file": "usr/bin/cm_testEXE"},
-    {"type": "exe", "file": "usr/bin/cm_testEXE"},
-    {"type": "pdb", "file": "usr/bin/cm_testEXE2"},
-    {"type": "exe", "file": "usr/bin/cm_testEXE2"}
+    {"type": "pdb", "file": "usr/bin/cm_meson_testEXE"},
+    {"type": "exe", "file": "usr/bin/cm_meson_testEXE"},
+    {"type": "pdb", "file": "usr/bin/cm_benchmark"},
+    {"type": "exe", "file": "usr/bin/cm_benchmark"}
   ],
   "tools": {
     "cmake": ">=3.11"