CMake: Added support for CMAKE_MODULE_PATH and extra CMake args (closes #4779)

pull/4862/head
Daniel Mensinger 6 years ago committed by Jussi Pakkanen
parent abad2ff005
commit e1a83793ae
  1. 8
      docs/markdown/Dependencies.md
  2. 17
      docs/markdown/howtox.md
  3. 9
      docs/markdown/snippets/cmake_module_path.md
  4. 20
      mesonbuild/dependencies/base.py
  5. 4
      mesonbuild/interpreter.py
  6. 9
      test cases/linuxlike/13 cmake dependency/cmake/FindSomethingLikeZLIB.cmake
  7. 6
      test cases/linuxlike/13 cmake dependency/meson.build

@ -148,6 +148,14 @@ it automatically.
cmake_dep = dependency('ZLIB', method : 'cmake', modules : ['ZLIB::ZLIB'])
```
It is also possible to reuse existing `Find<name>.cmake` files with the
`cmake_module_path` property. Using this property is equivalent to setting the
`CMAKE_MODULE_PATH` variable in CMake. The path(s) given to `cmake_module_path`
should all be relative to the project source directory. Absolute paths
should only be used if the CMake files are not stored in the project itself.
Additional CMake parameters can be specified with the `cmake_args` property.
### Some notes on Dub
Please understand that meson is only able to find dependencies that

@ -203,3 +203,20 @@ executable(..., dependencies : m_dep)
```meson
executable(..., install : true, install_dir : get_option('libexecdir'))
```
## Use existing `Find<name>.cmake` files
Meson can use the CMake `find_package()` ecosystem if CMake is installed.
To find a dependency with custom `Find<name>.cmake`, set the `cmake_module_path`
property to the path in your project where the CMake scripts are stored.
Example for a `FindCmakeOnlyDep.cmake` in a `cmake` subdirectory:
```meson
cm_dep = dependency('CmakeOnlyDep', cmake_module_path : 'cmake')
```
The `cmake_module_path` property is only needed for custom CMake scripts. System
wide CMake scripts are found automatically.
More information can be found [here](Dependencies.md#cmake)

@ -0,0 +1,9 @@
## Added `cmake_module_path` and `cmake_args` to dependency
The CMake dependency backend can now make use of existing `Find<name>.cmake`
files by setting the `CMAKE_MODULE_PATH` with the new `dependency()` property
`cmake_module_path`. The paths given to `cmake_module_path` should be relative
to the project source directory.
Furthermore the property `cmake_args` was added to give CMake additional
parameters.

@ -27,13 +27,14 @@ import textwrap
import platform
import itertools
import ctypes
from typing import List
from enum import Enum
from pathlib import Path, PurePath
from .. import mlog
from .. import mesonlib
from ..compilers import clib_langs
from ..environment import BinaryTable
from ..environment import BinaryTable, Environment
from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify
from ..mesonlib import Version
@ -926,7 +927,7 @@ class CMakeDependency(ExternalDependency):
def _gen_exception(self, msg):
return DependencyException('Dependency {} not found: {}'.format(self.name, msg))
def __init__(self, name, environment, kwargs, language=None):
def __init__(self, name: str, environment: Environment, kwargs, language=None):
super().__init__('cmake', environment, language, kwargs)
self.name = name
self.is_libtool = False
@ -1010,16 +1011,25 @@ class CMakeDependency(ExternalDependency):
return
modules = kwargs.get('modules', [])
cm_path = kwargs.get('cmake_module_path', [])
cm_args = kwargs.get('cmake_args', [])
if not isinstance(modules, list):
modules = [modules]
self._detect_dep(name, modules)
if not isinstance(cm_path, list):
cm_path = [cm_path]
if not isinstance(cm_args, list):
cm_args = [cm_args]
cm_path = [x if os.path.isabs(x) else os.path.join(environment.get_source_dir(), x) for x in cm_path]
if cm_path:
cm_args += ['-DCMAKE_MODULE_PATH={}'.format(';'.join(cm_path))]
self._detect_dep(name, modules, cm_args)
def __repr__(self):
s = '<{0} {1}: {2} {3}>'
return s.format(self.__class__.__name__, self.name, self.is_found,
self.version_reqs)
def _detect_dep(self, name, modules):
def _detect_dep(self, name: str, modules: List[str], args: List[str]):
# Detect a dependency with CMake using the '--find-package' mode
# and the trace output (stderr)
#
@ -1035,7 +1045,7 @@ class CMakeDependency(ExternalDependency):
mlog.debug('Try CMake generator: {}'.format(i if len(i) > 0 else 'auto'))
# Prepare options
cmake_opts = ['--trace-expand', '-DNAME={}'.format(name), '.']
cmake_opts = ['--trace-expand', '-DNAME={}'.format(name)] + args + ['.']
if len(i) > 0:
cmake_opts = ['-G', i] + cmake_opts

@ -1929,6 +1929,7 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
'main',
'method',
'modules',
'cmake_module_path',
'optional_modules',
'native',
'not_found_message',
@ -1936,6 +1937,7 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
'static',
'version',
'private_headers',
'cmake_args',
},
'declare_dependency': {'include_directories',
'link_with',
@ -2903,10 +2905,10 @@ external dependencies (including libraries) must go to "dependencies".''')
elif name == 'openmp':
FeatureNew('OpenMP Dependency', '0.46.0').use(self.subproject)
@FeatureNewKwargs('dependency', '0.50.0', ['not_found_message', 'cmake_module_path', 'cmake_args'])
@FeatureNewKwargs('dependency', '0.49.0', ['disabler'])
@FeatureNewKwargs('dependency', '0.40.0', ['method'])
@FeatureNewKwargs('dependency', '0.38.0', ['default_options'])
@FeatureNewKwargs('dependency', '0.50.0', ['not_found_message'])
@disablerIfNotFound
@permittedKwargs(permitted_kwargs['dependency'])
def func_dependency(self, node, args, kwargs):

@ -0,0 +1,9 @@
find_package(ZLIB)
if(ZLIB_FOUND OR ZLIB_Found)
set(SomethingLikeZLIB_FOUND ON)
set(SomethingLikeZLIB_LIBRARIES ${ZLIB_LIBRARY})
set(SomethingLikeZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
else()
set(SomethingLikeZLIB_FOUND OFF)
endif()

@ -36,6 +36,12 @@ depf2 = dependency('ZLIB', required : false, method : 'cmake', modules : 'dfggh:
assert(depf2.found() == false, 'Invalid CMake targets should fail')
# Try to find a dependency with a custom CMake module
depm1 = dependency('SomethingLikeZLIB', required : true, method : 'cmake', cmake_module_path : 'cmake')
depm2 = dependency('SomethingLikeZLIB', required : true, method : 'cmake', cmake_module_path : ['cmake'])
depm3 = dependency('SomethingLikeZLIB', required : true, cmake_module_path : 'cmake')
# Try to compile a test that takes a dep and an include_directories
cc = meson.get_compiler('c')

Loading…
Cancel
Save