coredata: add cmake_prefix_path option

pull/5423/head
Dylan Baker 6 years ago committed by Jussi Pakkanen
parent 0d19d334a8
commit 0714ba58c7
  1. 1
      docs/markdown/Builtin-options.md
  2. 16
      docs/markdown/snippets/cmake-prefix-path.md
  3. 8
      mesonbuild/coredata.py
  4. 22
      mesonbuild/dependencies/base.py
  5. 19
      run_unittests.py
  6. 4
      test cases/unit/60 cmake_prefix_path/meson.build
  7. 4
      test cases/unit/60 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake

@ -70,6 +70,7 @@ They have no effect when the host and build machines are the same.
| layout {mirror,flat} | mirror | Build directory layout | no |
| optimization {0, g, 1, 2, 3, s} | 0 | Optimization level | no |
| pkg_config_path | [] | Additional paths for pkg-config to search before builtin paths | yes |
| cmake_prefix_path | [] | Additional prefixes for cmake to search before builtin paths | yes |
| stdsplit | true | Split stdout and stderr in test logs | no |
| strip | false | Strip targets on install | no |
| unity {on, off, subprojects} | off | Unity build | no |

@ -0,0 +1,16 @@
## CMake prefix path overrides
When using pkg-config as a dependency resolver we can pass
`-Dpkg_config_path=$somepath` to extend or overwrite where pkg-config will
search for dependencies. Now cmake can do the same, as long as the dependency
uses a ${Name}Config.cmake file (not a Find{$Name}.cmake file), by passing
`-Dcmake_prefix_path=list,of,paths`. It is important that point this at the
prefix that the dependency is installed into, not the cmake path.
If you have installed something to `/tmp/dep`, which has a layout like:
```
/tmp/dep/lib/cmake
/tmp/dep/bin
```
then invoke meson as `meson builddir/ -Dcmake_prefix_path=/tmp/dep`

@ -235,6 +235,7 @@ class DependencyCacheType(enum.Enum):
OTHER = 0
PKG_CONFIG = 1
CMAKE = 2
@classmethod
def from_type(cls, dep: 'dependencies.Dependency') -> 'DependencyCacheType':
@ -242,6 +243,8 @@ class DependencyCacheType(enum.Enum):
# As more types gain search overrides they'll need to be added here
if isinstance(dep, dependencies.PkgConfigDependency):
return cls.PKG_CONFIG
if isinstance(dep, dependencies.CMakeDependency):
return cls.CMAKE
return cls.OTHER
@ -282,6 +285,10 @@ class DependencyCache:
if self.__is_cross:
return tuple(self.__builtins['cross_pkg_config_path'].value)
return tuple(self.__builtins['pkg_config_path'].value)
elif type_ is DependencyCacheType.CMAKE:
if self.__is_cross:
return tuple(self.__builtins['cross_cmake_prefix_path'].value)
return tuple(self.__builtins['cmake_prefix_path'].value)
assert type_ is DependencyCacheType.OTHER, 'Someone forgot to update subkey calculations for a new type'
return tuple()
@ -923,6 +930,7 @@ builtin_options = OrderedDict([
('install_umask', BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022')),
('layout', BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [], separate_cross=True)),
('cmake_prefix_path', BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [], separate_cross=True)),
('optimization', BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's'])),
('stdsplit', BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),

@ -1129,11 +1129,19 @@ class CMakeDependency(ExternalDependency):
modules = [(x, True) for x in stringlistify(extract_as_list(kwargs, 'modules'))]
modules += [(x, False) for x in stringlistify(extract_as_list(kwargs, 'optional_modules'))]
cm_path = stringlistify(extract_as_list(kwargs, 'cmake_module_path'))
cm_args = stringlistify(extract_as_list(kwargs, 'cmake_args'))
cm_path = [x if os.path.isabs(x) else os.path.join(environment.get_source_dir(), x) for x in cm_path]
cm_args = stringlistify(extract_as_list(kwargs, 'cmake_args'))
if cm_path:
cm_args += ['-DCMAKE_MODULE_PATH={}'.format(';'.join(cm_path))]
if not self._preliminary_find_check(name, cm_path, environment.machines[for_machine]):
cm_args.append('-DCMAKE_MODULE_PATH=' + ';'.join(cm_path))
if environment.is_cross_build() and self.want_cross:
pref_path = self.env.coredata.builtins['cross_cmake_prefix_path'].value
else:
pref_path = self.env.coredata.builtins['cmake_prefix_path'].value
if pref_path:
cm_args.append('-DCMAKE_PREFIX_PATH={}'.format(';'.join(pref_path)))
if not self._preliminary_find_check(name, cm_path, pref_path, environment.machines[for_machine]):
return
self._detect_dep(name, modules, cm_args)
@ -1229,7 +1237,7 @@ class CMakeDependency(ExternalDependency):
except OSError:
return False
def _preliminary_find_check(self, name: str, module_path: List[str], machine: MachineInfo) -> bool:
def _preliminary_find_check(self, name: str, module_path: List[str], prefix_path: List[str], machine: MachineInfo) -> bool:
lname = str(name).lower()
# Checks <path>, <path>/cmake, <path>/CMake
@ -1273,6 +1281,12 @@ class CMakeDependency(ExternalDependency):
if find_module(i):
return True
# Check the user provided prefix paths
for i in prefix_path:
if search_lib_dirs(i):
return True
# Check the system paths
for i in self.cmakeinfo['module_paths']:
if find_module(i):

@ -163,6 +163,20 @@ def skipIfNoPkgconfigDep(depname):
return wrapped
return wrapper
def skip_if_no_cmake(f):
'''
Skip this test if no cmake is found, unless we're on CI.
This allows users to run our test suite without having
cmake installed on, f.ex., macOS, while ensuring that our CI does not
silently skip the test because of misconfiguration.
'''
@functools.wraps(f)
def wrapped(*args, **kwargs):
if not is_ci() and shutil.which('cmake') is None:
raise unittest.SkipTest('cmake not found')
return f(*args, **kwargs)
return wrapped
def skip_if_not_language(lang):
def wrapper(func):
@functools.wraps(func)
@ -3662,6 +3676,11 @@ recommended as it is not supported on some platforms''')
# just test that the command does not fail (e.g. because it throws an exception)
self._run([*self.meson_command, 'unstable-coredata', self.builddir])
@skip_if_no_cmake
def test_cmake_prefix_path(self):
testdir = os.path.join(self.unit_test_dir, '60 cmake_prefix_path')
self.init(testdir, extra_args=['-Dcmake_prefix_path=' + os.path.join(testdir, 'prefix')])
class FailureTests(BasePlatformTests):
'''
Tests that test failure conditions. Build files here should be dynamically

@ -0,0 +1,4 @@
project('cmake prefix path test')
d = dependency('mesontest', method : 'cmake')
assert(d.version() == '1.2.3', 'Got the wrong version!')

@ -0,0 +1,4 @@
set(MESONTEST_VERSION "1.2.3")
set(MESONTEST_LIBRARIES "foo.so")
set(MESONTEST_INCLUDE_DIR "")
set(MESONTEST_FOUND "TRUE")
Loading…
Cancel
Save