diff options
-rw-r--r-- | mesonbuild/cmake/interpreter.py | 66 | ||||
-rw-r--r-- | mesonbuild/cmake/traceparser.py | 11 | ||||
-rw-r--r-- | test cases/cmake/16 threads/main.cpp | 9 | ||||
-rw-r--r-- | test cases/cmake/16 threads/meson.build | 8 | ||||
-rw-r--r-- | test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt | 9 | ||||
-rw-r--r-- | test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp | 15 | ||||
-rw-r--r-- | test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp | 10 | ||||
-rw-r--r-- | test cases/cmake/16 threads/subprojects/cmMod/main.cpp | 9 | ||||
-rw-r--r-- | test cases/cmake/2 advanced/meson.build | 5 | ||||
-rw-r--r-- | test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt | 8 | ||||
-rw-r--r-- | test cases/cmake/3 advanced no dep/meson.build | 5 | ||||
-rw-r--r-- | test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt | 5 |
12 files changed, 152 insertions, 8 deletions
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index 66d0994..5f887ee 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -301,6 +301,72 @@ class ConverterTarget: 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)$') + to_process = [self.cmake_name] + processed = [] + while len(to_process) > 0: + curr = to_process.pop(0) + + if curr in processed or curr not in trace.targets: + continue + + tgt = trace.targets[curr] + cfgs = [] + cfg = '' + otherDeps = [] + libraries = [] + mlog.debug(tgt) + + 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] + + if 'INTERFACE_COMPILE_OPTIONS' in tgt.properties: + self.public_compile_opts += [x for x in tgt.properties['INTERFACE_COMPILE_OPTIONS'] if x] + + if 'IMPORTED_CONFIGURATIONS' in tgt.properties: + cfgs += [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x] + cfg = cfgs[0] + + if 'CONFIGURATIONS' in tgt.properties: + cfgs += [x for x in tgt.properties['CONFIGURATIONS'] if x] + cfg = cfgs[0] + + if 'RELEASE' in cfgs: + cfg = 'RELEASE' + + if 'IMPORTED_IMPLIB_{}'.format(cfg) in tgt.properties: + libraries += [x for x in tgt.properties['IMPORTED_IMPLIB_{}'.format(cfg)] if x] + elif 'IMPORTED_IMPLIB' in tgt.properties: + libraries += [x for x in tgt.properties['IMPORTED_IMPLIB'] if x] + elif 'IMPORTED_LOCATION_{}'.format(cfg) in tgt.properties: + libraries += [x for x in tgt.properties['IMPORTED_LOCATION_{}'.format(cfg)] if x] + elif 'IMPORTED_LOCATION' in tgt.properties: + libraries += [x for x in tgt.properties['IMPORTED_LOCATION'] if x] + + if 'LINK_LIBRARIES' in tgt.properties: + otherDeps += [x for x in tgt.properties['LINK_LIBRARIES'] if x] + + if 'INTERFACE_LINK_LIBRARIES' in tgt.properties: + otherDeps += [x for x in tgt.properties['INTERFACE_LINK_LIBRARIES'] if x] + + if 'IMPORTED_LINK_DEPENDENT_LIBRARIES_{}'.format(cfg) in tgt.properties: + otherDeps += [x for x in tgt.properties['IMPORTED_LINK_DEPENDENT_LIBRARIES_{}'.format(cfg)] if x] + elif 'IMPORTED_LINK_DEPENDENT_LIBRARIES' in tgt.properties: + otherDeps += [x for x in tgt.properties['IMPORTED_LINK_DEPENDENT_LIBRARIES'] if x] + + for j in otherDeps: + if j in trace.targets: + to_process += [j] + elif reg_is_lib.match(j) or os.path.exists(j): + libraries += [j] + + for j in libraries: + if j not in self.link_libraries: + self.link_libraries += [j] + + processed += [curr] elif self.type.upper() not in ['EXECUTABLE', 'OBJECT_LIBRARY']: mlog.warning('CMake: Target', mlog.bold(self.cmake_name), 'not found in CMake trace. This can lead to build errors') diff --git a/mesonbuild/cmake/traceparser.py b/mesonbuild/cmake/traceparser.py index 50cabab..84b2120 100644 --- a/mesonbuild/cmake/traceparser.py +++ b/mesonbuild/cmake/traceparser.py @@ -89,6 +89,7 @@ class CMakeTraceParser: 'target_compile_definitions': self._cmake_target_compile_definitions, 'target_compile_options': self._cmake_target_compile_options, 'target_include_directories': self._cmake_target_include_directories, + 'target_link_libraries': self._cmake_target_link_libraries, 'target_link_options': self._cmake_target_link_options, 'add_dependencies': self._cmake_add_dependencies, } @@ -432,6 +433,10 @@ class CMakeTraceParser: # DOC: https://cmake.org/cmake/help/latest/command/target_link_options.html self._parse_common_target_options('target_link_options', 'LINK_OPTIONS', 'INTERFACE_LINK_OPTIONS', tline) + def _cmake_target_link_libraries(self, tline: CMakeTraceLine) -> None: + # DOC: https://cmake.org/cmake/help/latest/command/target_link_libraries.html + self._parse_common_target_options('target_link_options', 'LINK_LIBRARIES', 'INTERFACE_LINK_LIBRARIES', tline) + def _parse_common_target_options(self, func: str, private_prop: str, interface_prop: str, tline: CMakeTraceLine, ignore: Optional[List[str]] = None, paths: bool = False): if ignore is None: ignore = ['BEFORE'] @@ -453,14 +458,14 @@ class CMakeTraceParser: if i in ignore: continue - if i in ['INTERFACE', 'PUBLIC', 'PRIVATE']: + if i in ['INTERFACE', 'LINK_INTERFACE_LIBRARIES', 'PUBLIC', 'PRIVATE', 'LINK_PUBLIC', 'LINK_PRIVATE']: mode = i continue - if mode in ['INTERFACE', 'PUBLIC']: + if mode in ['INTERFACE', 'LINK_INTERFACE_LIBRARIES', 'PUBLIC', 'LINK_PUBLIC']: interface += [i] - if mode in ['PUBLIC', 'PRIVATE']: + if mode in ['PUBLIC', 'PRIVATE', 'LINK_PRIVATE']: private += [i] if paths: diff --git a/test cases/cmake/16 threads/main.cpp b/test cases/cmake/16 threads/main.cpp new file mode 100644 index 0000000..67ee110 --- /dev/null +++ b/test cases/cmake/16 threads/main.cpp @@ -0,0 +1,9 @@ +#include "cmMod.hpp" + +#include <cstdlib> + +int main() { + CmMod cc; + cc.asyncIncrement(); + return cc.getNum() == 1 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/test cases/cmake/16 threads/meson.build b/test cases/cmake/16 threads/meson.build new file mode 100644 index 0000000..d7ade1c --- /dev/null +++ b/test cases/cmake/16 threads/meson.build @@ -0,0 +1,8 @@ +project('cmMod', ['c', 'cpp']) + +cm = import('cmake') +cmMod = cm.subproject('cmMod') +cmModDep = cmMod.dependency('cmModLib') + +exe1 = executable('exe1', ['main.cpp'], dependencies: [cmModDep]) +test('exe1_OK', exe1) diff --git a/test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt new file mode 100644 index 0000000..37d32c1 --- /dev/null +++ b/test cases/cmake/16 threads/subprojects/cmMod/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.5) + +project(cmMod CXX) +set (CMAKE_CXX_STANDARD 14) + +find_package(Threads) + +add_library(cmModLib STATIC cmMod.cpp) +target_link_libraries(cmModLib PRIVATE Threads::Threads) diff --git a/test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp new file mode 100644 index 0000000..f971eeb --- /dev/null +++ b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.cpp @@ -0,0 +1,15 @@ +#include "cmMod.hpp" + +#include <chrono> +#include <thread> + +using namespace std::chrono_literals; + +void CmMod::asyncIncrement() { + std::thread t1([this]() { + std::this_thread::sleep_for(100ms); + num += 1; + }); + + t1.join(); +} diff --git a/test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp new file mode 100644 index 0000000..1c85a8b --- /dev/null +++ b/test cases/cmake/16 threads/subprojects/cmMod/cmMod.hpp @@ -0,0 +1,10 @@ +#pragma once + +class CmMod { +private: + int num = 0; + +public: + inline int getNum() const { return num; } + void asyncIncrement(); +}; diff --git a/test cases/cmake/16 threads/subprojects/cmMod/main.cpp b/test cases/cmake/16 threads/subprojects/cmMod/main.cpp new file mode 100644 index 0000000..67ee110 --- /dev/null +++ b/test cases/cmake/16 threads/subprojects/cmMod/main.cpp @@ -0,0 +1,9 @@ +#include "cmMod.hpp" + +#include <cstdlib> + +int main() { + CmMod cc; + cc.asyncIncrement(); + return cc.getNum() == 1 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/test cases/cmake/2 advanced/meson.build b/test cases/cmake/2 advanced/meson.build index 385a49b..a10db1c 100644 --- a/test cases/cmake/2 advanced/meson.build +++ b/test cases/cmake/2 advanced/meson.build @@ -10,11 +10,14 @@ cm = import('cmake') # Test the "normal" subproject call sub_pro = cm.subproject('cmMod') sub_dep = sub_pro.dependency('cmModLib') +sub_sta = sub_pro.dependency('cmModLibStatic') # Build some files exe1 = executable('main1', ['main.cpp'], dependencies: [sub_dep]) +exe2 = executable('main2', ['main.cpp'], dependencies: [sub_sta]) 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('test2', sub_pro.target('testEXE')) +test('test3', sub_pro.target('testEXE')) diff --git a/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt index 05ccb9e..50b1049 100644 --- a/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt +++ b/test cases/cmake/2 advanced/subprojects/cmMod/CMakeLists.txt @@ -10,7 +10,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CM set(CONFIG_OPT 42) configure_file("config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) -add_library(cmModLib SHARED lib/cmMod.cpp) +add_library(cmModLib SHARED lib/cmMod.cpp) +add_library(cmModLibStatic STATIC lib/cmMod.cpp) include(GenerateExportHeader) generate_export_header(cmModLib) @@ -18,7 +19,10 @@ set_target_properties(cmModLib PROPERTIES VERSION 1.0.1) add_executable(testEXE main.cpp) -target_link_libraries(cmModLib ZLIB::ZLIB) +target_link_libraries(cmModLib ZLIB::ZLIB) +target_link_libraries(cmModLibStatic ZLIB::ZLIB) target_link_libraries(testEXE cmModLib) +target_compile_definitions(cmModLibStatic PUBLIC CMMODLIB_STATIC_DEFINE) + install(TARGETS cmModLib testEXE LIBRARY DESTINATION lib RUNTIME DESTINATION bin) diff --git a/test cases/cmake/3 advanced no dep/meson.build b/test cases/cmake/3 advanced no dep/meson.build index c10dbf5..0d1e127 100644 --- a/test cases/cmake/3 advanced no dep/meson.build +++ b/test cases/cmake/3 advanced no dep/meson.build @@ -5,11 +5,14 @@ cm = import('cmake') # Test the "normal" subproject call sub_pro = cm.subproject('cmMod') sub_dep = sub_pro.dependency('cmModLib') +sub_sta = sub_pro.dependency('cmModLibStatic') # Build some files exe1 = executable('main1', ['main.cpp'], dependencies: [sub_dep]) +exe2 = executable('main2', ['main.cpp'], dependencies: [sub_sta]) 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('test2', sub_pro.target('testEXE')) +test('test3', sub_pro.target('testEXE')) 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 index 2f6267d..38c1fff 100644 --- a/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt +++ b/test cases/cmake/3 advanced no dep/subprojects/cmMod/CMakeLists.txt @@ -8,7 +8,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CM set(CONFIG_OPT 42) configure_file("config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) -add_library(cmModLib SHARED lib/cmMod.cpp) +add_library(cmModLib SHARED lib/cmMod.cpp) +add_library(cmModLibStatic STATIC lib/cmMod.cpp) include(GenerateExportHeader) generate_export_header(cmModLib) @@ -18,4 +19,6 @@ add_executable(testEXE main.cpp) target_link_libraries(testEXE cmModLib) +target_compile_definitions(cmModLibStatic PUBLIC CMMODLIB_STATIC_DEFINE) + install(TARGETS cmModLib testEXE LIBRARY DESTINATION lib RUNTIME DESTINATION bin) |