cmake: Implement support for interpreting link "keywords"

CMakes `target_link_libraries()` supports certain keywords to
only enable specific libraries for specific CMake configurations.
We now try our best to replicate this for Meson dependencies.

Fixes #9197
pull/9361/head
Daniel Mensinger 3 years ago
parent f1614a6071
commit 29c2b44a29
  1. 42
      mesonbuild/dependencies/cmake.py
  2. 2
      test cases/linuxlike/13 cmake dependency/cmake_fake1/cmMesonTestF1Config.cmake
  3. 4
      test cases/linuxlike/13 cmake dependency/meson.build

@ -433,6 +433,18 @@ class CMakeDependency(ExternalDependency):
modules = self._map_module_list(modules, components)
autodetected_module_list = False
# Check if we need a DEBUG or RELEASE CMake dependencies
is_debug = False
if OptionKey('b_vscrt') in self.env.coredata.options:
is_debug = self.env.coredata.get_option(OptionKey('buildtype')) == 'debug'
if self.env.coredata.options[OptionKey('b_vscrt')].value in {'mdd', 'mtd'}:
is_debug = True
else:
# Don't directly assign to is_debug to make mypy happy
debug_opt = self.env.coredata.get_option(OptionKey('debug'))
assert isinstance(debug_opt, bool)
is_debug = debug_opt
# Try guessing a CMake target if none is provided
if len(modules) == 0:
for i in self.traceparser.targets:
@ -479,7 +491,26 @@ class CMakeDependency(ExternalDependency):
incDirs = [x for x in self.traceparser.get_cmake_var('PACKAGE_INCLUDE_DIRS') if x]
defs = [x for x in self.traceparser.get_cmake_var('PACKAGE_DEFINITIONS') if x]
libs = [x for x in self.traceparser.get_cmake_var('PACKAGE_LIBRARIES') if x]
libs_raw = [x for x in self.traceparser.get_cmake_var('PACKAGE_LIBRARIES') if x]
# CMake has a "fun" API, where certain keywords describing
# configurations can be in the *_LIBRARIES vraiables. See:
# - https://github.com/mesonbuild/meson/issues/9197
# - https://gitlab.freedesktop.org/libnice/libnice/-/issues/140
# - https://cmake.org/cmake/help/latest/command/target_link_libraries.html#overview (the last point in the section)
libs: T.List[str] = []
cfg_matches = True
cm_tag_map = {'debug': is_debug, 'optimized': not is_debug, 'general': True}
for i in libs_raw:
if i.lower() in cm_tag_map:
cfg_matches = cm_tag_map[i.lower()]
continue
if cfg_matches:
libs += [i]
# According to the CMake docs, a keyword only works for the
# directly the following item and all items without a keyword
# are implizitly `general`
cfg_matches = True
# Try to use old style variables if no module is specified
if len(libs) > 0:
@ -545,15 +576,6 @@ class CMakeDependency(ExternalDependency):
cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x]
cfg = cfgs[0]
if OptionKey('b_vscrt') in self.env.coredata.options:
is_debug = self.env.coredata.get_option(OptionKey('buildtype')) == 'debug'
if self.env.coredata.options[OptionKey('b_vscrt')].value in {'mdd', 'mtd'}:
is_debug = True
else:
# Don't directly assign to is_debug to make mypy happy
debug_opt = self.env.coredata.get_option(OptionKey('debug'))
assert isinstance(debug_opt, bool)
is_debug = debug_opt
if is_debug:
if 'DEBUG' in cfgs:
cfg = 'DEBUG'

@ -2,7 +2,7 @@ find_package(ZLIB)
if(ZLIB_FOUND OR ZLIB_Found)
set(cmMesonTestF1_FOUND ON)
set(cmMesonTestF1_LIBRARIES ${ZLIB_LIBRARY})
set(cmMesonTestF1_LIBRARIES general ${ZLIB_LIBRARY})
set(cmMesonTestF1_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
add_library(CMMesonTESTf1::evil_non_standard_trget UNKNOWN IMPORTED)

@ -48,6 +48,10 @@ depPrefEnv1 = dependency('cmMesonTestF1', required : true, method : 'cmake')
depPrefEnv2 = dependency('cmMesonTestF2', required : true, method : 'cmake')
depPrefEnv3 = dependency('cmMesonTestF3', required : true, method : 'cmake')
# Try to actually link with depPrefEnv1, since we are doing "fun" stuff there
exe3 = executable('zlibprog3', 'prog.c', dependencies : depPrefEnv1)
test('zlibtest3', exe3)
# Try to find a dependency with a custom CMake module
depm1 = dependency('SomethingLikeZLIB', required : true, components : 'required_comp', method : 'cmake', cmake_module_path : 'cmake')

Loading…
Cancel
Save