aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Builtin-options.md1
-rw-r--r--docs/markdown/snippets/cmake-prefix-path.md16
-rw-r--r--mesonbuild/coredata.py8
-rw-r--r--mesonbuild/dependencies/base.py22
-rwxr-xr-xrun_unittests.py19
-rw-r--r--test cases/unit/60 cmake_prefix_path/meson.build4
-rw-r--r--test cases/unit/60 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake4
7 files changed, 70 insertions, 4 deletions
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index 1d6f9f9..9c87aef 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -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 |
diff --git a/docs/markdown/snippets/cmake-prefix-path.md b/docs/markdown/snippets/cmake-prefix-path.md
new file mode 100644
index 0000000..15497b8
--- /dev/null
+++ b/docs/markdown/snippets/cmake-prefix-path.md
@@ -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`
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index ac620d7..e1dd74b 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -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)),
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 37a8847..1ccbf6f 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -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):
diff --git a/run_unittests.py b/run_unittests.py
index d64e60e..b477aa3 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -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
diff --git a/test cases/unit/60 cmake_prefix_path/meson.build b/test cases/unit/60 cmake_prefix_path/meson.build
new file mode 100644
index 0000000..442bbd3
--- /dev/null
+++ b/test cases/unit/60 cmake_prefix_path/meson.build
@@ -0,0 +1,4 @@
+project('cmake prefix path test')
+
+d = dependency('mesontest', method : 'cmake')
+assert(d.version() == '1.2.3', 'Got the wrong version!')
diff --git a/test cases/unit/60 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake b/test cases/unit/60 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake
new file mode 100644
index 0000000..289b349
--- /dev/null
+++ b/test cases/unit/60 cmake_prefix_path/prefix/lib/cmake/mesontest/mesontest-config.cmake
@@ -0,0 +1,4 @@
+set(MESONTEST_VERSION "1.2.3")
+set(MESONTEST_LIBRARIES "foo.so")
+set(MESONTEST_INCLUDE_DIR "")
+set(MESONTEST_FOUND "TRUE")