diff --git a/docs/markdown/snippets/cmake-project-version.md b/docs/markdown/snippets/cmake-project-version.md new file mode 100644 index 000000000..0bc120b9f --- /dev/null +++ b/docs/markdown/snippets/cmake-project-version.md @@ -0,0 +1,6 @@ +## Meson now reads the project version of cmake subprojects + +CMake subprojects configured by meson will now have their project +version set to the project version in their CMakeLists.txt. This +allows version constraints to be properly checked when falling back to +a cmake subproject. diff --git a/mesonbuild/cmake/fileapi.py b/mesonbuild/cmake/fileapi.py index baf499fc0..c82c51fc0 100644 --- a/mesonbuild/cmake/fileapi.py +++ b/mesonbuild/cmake/fileapi.py @@ -30,8 +30,10 @@ class CMakeFileAPI: self.reply_dir = self.api_base_dir / 'reply' self.cmake_sources: T.List[CMakeBuildFile] = [] self.cmake_configurations: T.List[CMakeConfiguration] = [] + self.project_version = '' self.kind_resolver_map = { 'codemodel': self._parse_codemodel, + 'cache': self._parse_cache, 'cmakeFiles': self._parse_cmakeFiles, } @@ -41,12 +43,16 @@ class CMakeFileAPI: def get_cmake_configurations(self) -> T.List[CMakeConfiguration]: return self.cmake_configurations + def get_project_version(self) -> str: + return self.project_version + def setup_request(self) -> None: self.request_dir.mkdir(parents=True, exist_ok=True) query = { 'requests': [ {'kind': 'codemodel', 'version': {'major': 2, 'minor': 0}}, + {'kind': 'cache', 'version': {'major': 2, 'minor': 0}}, {'kind': 'cmakeFiles', 'version': {'major': 1, 'minor': 0}}, ] } @@ -279,6 +285,13 @@ class CMakeFileAPI: path = path if path.is_absolute() else src_dir / path self.cmake_sources += [CMakeBuildFile(path, i.get('isCMake', False), i.get('isGenerated', False))] + def _parse_cache(self, data: T.Dict[str, T.Any]) -> None: + assert 'entries' in data + + for e in data['entries']: + if e['name'] == 'CMAKE_PROJECT_VERSION': + self.project_version = e['value'] + def _strip_data(self, data: T.Any) -> T.Any: if isinstance(data, list): for idx, i in enumerate(data): diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index 8e9ea187e..20348b5f6 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -784,6 +784,7 @@ class CMakeInterpreter: # Analysed data self.project_name = '' + self.project_version = '' self.languages: T.List[str] = [] self.targets: T.List[ConverterTarget] = [] self.custom_targets: T.List[ConverterCustomTarget] = [] @@ -875,6 +876,8 @@ class CMakeInterpreter: # Load the codemodel configurations self.codemodel_configs = self.fileapi.get_cmake_configurations() + self.project_version = self.fileapi.get_project_version() + def analyse(self) -> None: if self.codemodel_configs is None: raise CMakeException('CMakeInterpreter was not initialized') @@ -949,7 +952,7 @@ class CMakeInterpreter: for tgt in self.targets: tgt.cleanup_dependencies() - mlog.log('CMake project', mlog.bold(self.project_name), 'has', mlog.bold(str(len(self.targets) + len(self.custom_targets))), 'build targets.') + mlog.log('CMake project', mlog.bold(self.project_name), mlog.bold(self.project_version), 'has', mlog.bold(str(len(self.targets) + len(self.custom_targets))), 'build targets.') def pretend_to_be_meson(self, options: TargetOptions) -> CodeBlockNode: if not self.project_name: @@ -1023,7 +1026,7 @@ class CMakeInterpreter: # Generate the root code block and the project function call root_cb = CodeBlockNode(token()) - root_cb.lines += [function('project', [self.project_name] + self.languages)] + root_cb.lines += [function('project', [self.project_name] + self.languages, {'version': self.project_version} if self.project_version else None)] # Add the run script for custom commands diff --git a/test cases/cmake/27 dependency fallback/meson.build b/test cases/cmake/27 dependency fallback/meson.build index 871d70c9f..76230bbf6 100644 --- a/test cases/cmake/27 dependency fallback/meson.build +++ b/test cases/cmake/27 dependency fallback/meson.build @@ -1,7 +1,7 @@ project('cmakeSubTest', ['c', 'cpp']) # Fallback to a CMake subproject -sub_dep = dependency('cmModLib++') +sub_dep = dependency('cmModLib++', version: '>=1.2.3') exe1 = executable('main', ['main.cpp'], dependencies: [sub_dep]) test('test1', exe1) diff --git a/test cases/cmake/27 dependency fallback/subprojects/cmMod/CMakeLists.txt b/test cases/cmake/27 dependency fallback/subprojects/cmMod/CMakeLists.txt index d08e55cdf..f920576e2 100644 --- a/test cases/cmake/27 dependency fallback/subprojects/cmMod/CMakeLists.txt +++ b/test cases/cmake/27 dependency fallback/subprojects/cmMod/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5) -project(cmMod) +project(cmMod VERSION 1.2.3) set(CMAKE_CXX_STANDARD 14) include_directories(${CMAKE_CURRENT_BINARY_DIR})