Skip to content

Commit c93db8e

Browse files
committed
CMake Toolchain
1 parent e9b4de0 commit c93db8e

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

cppython/plugins/cmake/builder.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from pathlib import Path
44

5-
from cppython.plugins.cmake.schema import CMakeData, CMakePresets, CMakeSyncData, ConfigurePreset
5+
from cppython.plugins.cmake.schema import CacheVariable, CMakeData, CMakePresets, CMakeSyncData, ConfigurePreset
66

77

88
class Builder:
@@ -21,10 +21,18 @@ def generate_provider_preset(provider_data: CMakeSyncData) -> CMakePresets:
2121
"""
2222
generated_configure_preset = ConfigurePreset(name=provider_data.provider_name, hidden=True)
2323

24-
# Toss in that sync data from the provider
25-
generated_configure_preset.cacheVariables = {
26-
'CMAKE_PROJECT_TOP_LEVEL_INCLUDES': str(provider_data.top_level_includes.as_posix()),
27-
}
24+
# Handle both top_level_includes and toolchain options
25+
cache_variables: dict[str, str | bool | CacheVariable | None] = {}
26+
27+
if provider_data.top_level_includes:
28+
cache_variables['CMAKE_PROJECT_TOP_LEVEL_INCLUDES'] = str(provider_data.top_level_includes.as_posix())
29+
30+
if provider_data.toolchain:
31+
# Use the toolchainFile field for better integration
32+
generated_configure_preset.toolchainFile = provider_data.toolchain
33+
34+
if cache_variables:
35+
generated_configure_preset.cacheVariables = cache_variables
2836

2937
return CMakePresets(configurePresets=[generated_configure_preset])
3038

cppython/plugins/cmake/schema.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class ConfigurePreset(CPPythonModel, extra='allow'):
5858
str | None,
5959
Field(description='The path to the output binary directory.'),
6060
] = None
61+
toolchainFile: Annotated[
62+
Path | None,
63+
Field(description='Path to the toolchain file.'),
64+
] = None
6165
cacheVariables: dict[str, None | bool | str | CacheVariable] | None = None
6266

6367

@@ -77,7 +81,13 @@ class CMakePresets(CPPythonModel, extra='allow'):
7781
class CMakeSyncData(SyncData):
7882
"""The CMake sync data"""
7983

80-
top_level_includes: FilePath
84+
top_level_includes: FilePath | None = None
85+
toolchain: Path | None = None # We don't resolve the toolchain until after we set it
86+
87+
def model_post_init(self, __context) -> None:
88+
"""Validate that at least one of top_level_includes or toolchain is provided."""
89+
if not self.top_level_includes and not self.toolchain:
90+
raise ValueError("Either 'top_level_includes' or 'toolchain' must be provided")
8191

8292

8393
class CMakeData(CPPythonModel):

cppython/plugins/conan/builder.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def _create_conanfile(conan_file: Path, dependencies: list[ConanDependency], nam
125125
"""Creates a conanfile.py file with the necessary content."""
126126
template_string = """
127127
from conan import ConanFile
128-
from conan.tools.cmake import CMake, CMakeDeps, cmake_layout
128+
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
129129
130130
class AutoPackage(ConanFile):
131131
name = "${name}"
@@ -139,6 +139,8 @@ def layout(self):
139139
def generate(self):
140140
deps = CMakeDeps(self)
141141
deps.generate()
142+
tc = CMakeToolchain(self)
143+
tc.generate()
142144
143145
def build(self):
144146
cmake = CMake(self)

cppython/plugins/conan/plugin.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from pathlib import Path
99
from typing import Any
1010

11-
import requests
1211
from conan.api.conan_api import ConanAPI
1312
from conan.api.model import ListPattern
1413

@@ -27,8 +26,6 @@
2726
class ConanProvider(Provider):
2827
"""Conan Provider"""
2928

30-
_provider_url = 'https://raw.githubusercontent.com/conan-io/cmake-conan/refs/heads/develop2/conan_provider.cmake'
31-
3229
def __init__(
3330
self, group_data: ProviderPluginGroupData, core_data: CorePluginData, configuration_data: dict[str, Any]
3431
) -> None:
@@ -39,15 +36,6 @@ def __init__(
3936

4037
self.builder = Builder()
4138

42-
@staticmethod
43-
def _download_file(url: str, file: Path) -> None:
44-
"""Replaces the given file with the contents of the url"""
45-
file.parent.mkdir(parents=True, exist_ok=True)
46-
47-
with open(file, 'wb') as out_file:
48-
content = requests.get(url, stream=True).content
49-
out_file.write(content)
50-
5139
@staticmethod
5240
def features(directory: Path) -> SupportedFeatures:
5341
"""Queries conan support
@@ -197,6 +185,13 @@ def _generate_consumer_files(self, conan_api: ConanAPI, deps_graph) -> None:
197185
output_folder=str(self.core_data.cppython_data.build_path),
198186
)
199187

188+
# Rename the generated toolchain file so our wrapper can include it
189+
original_toolchain = self.core_data.cppython_data.build_path / 'conan_toolchain.cmake'
190+
renamed_toolchain = self.core_data.cppython_data.build_path / 'conan_toolchain.cmake.real'
191+
192+
if original_toolchain.exists() and not renamed_toolchain.exists():
193+
original_toolchain.rename(renamed_toolchain)
194+
200195
def install(self) -> None:
201196
"""Installs the provider"""
202197
self._install_dependencies(update=False)
@@ -231,17 +226,25 @@ def sync_data(self, consumer: SyncConsumer) -> SyncData:
231226
"""
232227
for sync_type in consumer.sync_types():
233228
if sync_type == CMakeSyncData:
229+
# Use the CMakeToolchain file directly as the toolchain
230+
toolchain_path = self.core_data.cppython_data.build_path / 'conan_toolchain.cmake'
231+
234232
return CMakeSyncData(
235233
provider_name=TypeName('conan'),
236-
top_level_includes=self.core_data.cppython_data.install_path / 'conan_provider.cmake',
234+
toolchain=toolchain_path,
237235
)
238236

239237
raise NotSupportedError(f'Unsupported sync types: {consumer.sync_types()}')
240238

241239
@classmethod
242240
async def download_tooling(cls, directory: Path) -> None:
243-
"""Downloads the conan provider file"""
244-
cls._download_file(cls._provider_url, directory / 'conan_provider.cmake')
241+
"""Download external tooling required by the Conan provider.
242+
243+
Since we're using CMakeToolchain generator instead of cmake-conan provider,
244+
no external tooling needs to be downloaded.
245+
"""
246+
# No external tooling required when using CMakeToolchain
247+
pass
245248

246249
def publish(self) -> None:
247250
"""Publishes the package using conan create workflow."""

0 commit comments

Comments
 (0)