cmake: parse project version

This properly sets the project version in projects meson generates from
cmake projects. This allows dependency fallbacks to properly check the
version constraints in dependency calls when falling back to a cmake
subproject. Before this would fail, because the project version was
undefined.
This commit is contained in:
Nicolas Werner 2023-12-09 23:13:01 +01:00 committed by Eli Schwartz
parent f6f46173c4
commit ebf5757c59
5 changed files with 26 additions and 4 deletions

View File

@ -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.

View File

@ -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):

View File

@ -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

View File

@ -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)

View File

@ -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})