diff --git a/mesonbuild/cmake/fileapi.py b/mesonbuild/cmake/fileapi.py index 9605f920d..6b431b923 100644 --- a/mesonbuild/cmake/fileapi.py +++ b/mesonbuild/cmake/fileapi.py @@ -156,9 +156,6 @@ class CMakeFileAPI: if i['role'] == 'flags': link_flags += [i['fragment']] - # TODO The `dependencies` entry is new in the file API. - # maybe we can make use of that in addition to the - # implicit dependency detection tgt_data = { 'artifacts': [Path(x.get('path', '')) for x in tgt.get('artifacts', [])], 'sourceDirectory': src_dir, @@ -172,6 +169,8 @@ class CMakeFileAPI: 'linkFlags': ' '.join(link_flags), # See previous comment block why we join the array 'type': tgt.get('type', 'EXECUTABLE'), 'fileGroups': [], + 'cmakeId': tgt.get('id', ''), + 'dependencies': [dep.get('id', '') for dep in tgt.get('dependencies', [])], } processed_src_idx = [] @@ -257,6 +256,27 @@ class CMakeFileAPI: return pro_data + def find_target(cnf_data: T.Dict[str, T.Any], id: str) -> T.Optional[T.Dict[str, T.Any]]: + for project in cnf_data['projects']: + for target in project['targets']: # type: T.Dict[str, T.Any] + if target['cmakeId'] == id: + return target + return None + + def flatten_dependencies(cnf_data: T.Dict[str, T.Any]) -> None: + for project in cnf_data['projects']: + for target in project['targets']: + for dep_id in target.get('dependencies', '[]'): + dep = find_target(cnf_data, dep_id) + if dep is None: + mlog.warning('CMake: unknown target id', mlog.bold(dep_id), 'as a dependency of target', mlog.bold(target['name'])) + continue + + if dep['type'] == 'STATIC_LIBRARY': + if target['linkLibraries']: + target['linkLibraries'] += ' ' + target['linkLibraries'] += ' '.join(str(a) for a in dep['artifacts']) + for cnf in data.get('configurations', []): cnf_data = { 'name': cnf.get('name', ''), @@ -266,6 +286,7 @@ class CMakeFileAPI: for pro in cnf.get('projects', []): cnf_data['projects'] += [parse_project(pro)] + flatten_dependencies(cnf_data) self.cmake_configurations += [CMakeConfiguration(cnf_data)] def _parse_cmakeFiles(self, data: T.Dict[str, T.Any]) -> None: diff --git a/test cases/cmake/27 cmake static lib subproject/main.cc b/test cases/cmake/27 cmake static lib subproject/main.cc new file mode 100644 index 000000000..82314c550 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/main.cc @@ -0,0 +1,5 @@ +#include + +int main() { + c(); +} diff --git a/test cases/cmake/27 cmake static lib subproject/meson.build b/test cases/cmake/27 cmake static lib subproject/meson.build new file mode 100644 index 000000000..cb6ce8c92 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/meson.build @@ -0,0 +1,4 @@ +project('cmake-static-lib-subproject', 'cpp') + +libc = import('cmake').subproject('liba').dependency('libc') +executable('main', 'main.cc', dependencies: [libc]) diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/CMakeLists.txt b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/CMakeLists.txt new file mode 100644 index 000000000..560c3e8c4 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.20) +project(liba CXX) +add_subdirectory(libb) +add_subdirectory(libc) diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/CMakeLists.txt b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/CMakeLists.txt new file mode 100644 index 000000000..3ce916ce4 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/CMakeLists.txt @@ -0,0 +1,3 @@ +project(libb CXX) +add_library(libb src/libb.cc) +target_include_directories(libb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/src/libb.cc b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/src/libb.cc new file mode 100644 index 000000000..999145f54 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/src/libb.cc @@ -0,0 +1 @@ +void b() {} diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/src/libb.h b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/src/libb.h new file mode 100644 index 000000000..8bc68e091 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libb/src/libb.h @@ -0,0 +1 @@ +void b(); diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/CMakeLists.txt b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/CMakeLists.txt new file mode 100644 index 000000000..8fdcee049 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/CMakeLists.txt @@ -0,0 +1,4 @@ +project(libc CXX) +add_library(libc src/libc.cc) +target_link_libraries(libc libb) +target_include_directories(libc INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/src/libc.cc b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/src/libc.cc new file mode 100644 index 000000000..465c5bf83 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/src/libc.cc @@ -0,0 +1,5 @@ +#include + +void c() { + b(); +} diff --git a/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/src/libc.h b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/src/libc.h new file mode 100644 index 000000000..d7b7552e8 --- /dev/null +++ b/test cases/cmake/27 cmake static lib subproject/subprojects/liba/libc/src/libc.h @@ -0,0 +1 @@ +void c();