hatch-cpp 0.4.0__py3-none-any.whl → 0.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
hatch_cpp/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.4.0"
1
+ __version__ = "0.4.1"
2
2
 
3
3
  from .config import *
4
4
  from .hooks import *
hatch_cpp/config.py CHANGED
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  from os import environ, system as system_call
4
4
  from pathlib import Path
5
- from typing import List, Optional
6
5
 
7
6
  from pkn import getSimpleLogger
8
7
  from pydantic import BaseModel, Field, model_validator
@@ -21,13 +20,13 @@ log = getSimpleLogger("hatch_cpp")
21
20
  class HatchCppBuildConfig(BaseModel):
22
21
  """Build config values for Hatch C++ Builder."""
23
22
 
24
- verbose: Optional[bool] = Field(default=False)
25
- skip: Optional[bool] = Field(default=False)
26
- name: Optional[str] = Field(default=None)
27
- libraries: List[HatchCppLibrary] = Field(default_factory=list)
28
- cmake: Optional[HatchCppCmakeConfiguration] = Field(default=None)
29
- platform: Optional[HatchCppPlatform] = Field(default_factory=HatchCppPlatform.default)
30
- vcpkg: Optional[HatchCppVcpkgConfiguration] = Field(default_factory=HatchCppVcpkgConfiguration)
23
+ verbose: bool | None = Field(default=False)
24
+ skip: bool | None = Field(default=False)
25
+ name: str | None = Field(default=None)
26
+ libraries: list[HatchCppLibrary] = Field(default_factory=list)
27
+ cmake: HatchCppCmakeConfiguration | None = Field(default=None)
28
+ platform: HatchCppPlatform | None = Field(default_factory=HatchCppPlatform.default)
29
+ vcpkg: HatchCppVcpkgConfiguration | None = Field(default_factory=HatchCppVcpkgConfiguration)
31
30
 
32
31
  @model_validator(mode="wrap")
33
32
  @classmethod
@@ -56,9 +55,9 @@ class HatchCppBuildConfig(BaseModel):
56
55
 
57
56
  class HatchCppBuildPlan(HatchCppBuildConfig):
58
57
  build_type: BuildType = "release"
59
- commands: List[str] = Field(default_factory=list)
58
+ commands: list[str] = Field(default_factory=list)
60
59
 
61
- _active_toolchains: List[Toolchain] = []
60
+ _active_toolchains: list[Toolchain] = []
62
61
 
63
62
  def generate(self):
64
63
  self.commands = []
hatch_cpp/hooks.py CHANGED
@@ -1,10 +1,8 @@
1
- from typing import Type
2
-
3
1
  from hatchling.plugin import hookimpl
4
2
 
5
3
  from .plugin import HatchCppBuildHook
6
4
 
7
5
 
8
6
  @hookimpl
9
- def hatch_register_build_hook() -> Type[HatchCppBuildHook]:
7
+ def hatch_register_build_hook() -> type[HatchCppBuildHook]:
10
8
  return HatchCppBuildHook
hatch_cpp/plugin.py CHANGED
@@ -82,7 +82,7 @@ class HatchCppBuildHook(BuildHookInterface[HatchCppBuildConfig]):
82
82
  os_name = "linux"
83
83
  else:
84
84
  os_name = "win"
85
- if all([lib.py_limited_api for lib in build_plan.libraries]):
85
+ if all(lib.py_limited_api for lib in build_plan.libraries):
86
86
  build_data["tag"] = f"cp{version_major}{version_minor}-abi3-{os_name}_{machine}"
87
87
  else:
88
88
  build_data["tag"] = f"cp{version_major}{version_minor}-cp{version_major}{version_minor}-{os_name}_{machine}"
@@ -70,7 +70,7 @@ else()
70
70
  endif()
71
71
 
72
72
 
73
- find_package(Python ${CSP_PYTHON_VERSION} EXACT REQUIRED COMPONENTS Interpreter Development.Module)
73
+ find_package(Python ${HATCH_CPP_TEST_PROJECT_BASIC_PYTHON_VERSION} EXACT REQUIRED COMPONENTS Interpreter Development.Module)
74
74
 
75
75
  include_directories("${CMAKE_SOURCE_DIR}/cpp")
76
76
 
@@ -70,7 +70,7 @@ else()
70
70
  endif()
71
71
 
72
72
 
73
- find_package(Python ${CSP_PYTHON_VERSION} EXACT REQUIRED COMPONENTS Interpreter Development.Module)
73
+ find_package(Python ${HATCH_CPP_TEST_PROJECT_BASIC_PYTHON_VERSION} EXACT REQUIRED COMPONENTS Interpreter Development.Module)
74
74
 
75
75
  include_directories("${CMAKE_SOURCE_DIR}/cpp")
76
76
 
@@ -14,7 +14,6 @@ class TestProject:
14
14
  [
15
15
  "test_project_basic",
16
16
  "test_project_override_classes",
17
- "test_project_override_classes",
18
17
  "test_project_override_toolchain",
19
18
  "test_project_pybind",
20
19
  "test_project_pybind_vcpkg",
@@ -153,6 +153,27 @@ class TestVcpkgGenerate:
153
153
  assert not any("checkout" in cmd for cmd in commands)
154
154
  assert any("git clone" in cmd for cmd in commands)
155
155
 
156
+ def test_generate_uses_posix_command_paths(self, tmp_path, monkeypatch):
157
+ monkeypatch.chdir(tmp_path)
158
+ self._make_vcpkg_env(tmp_path)
159
+
160
+ cfg = HatchCppVcpkgConfiguration(vcpkg_triplet="x64-linux")
161
+ commands = cfg.generate(None)
162
+
163
+ assert "./vcpkg/bootstrap-vcpkg.sh" in commands
164
+ assert "./vcpkg/vcpkg install --triplet x64-linux" in commands
165
+
166
+ def test_generate_uses_windows_command_paths(self, tmp_path, monkeypatch):
167
+ monkeypatch.chdir(tmp_path)
168
+ monkeypatch.setattr("hatch_cpp.toolchains.vcpkg.sys_platform", "win32")
169
+ self._make_vcpkg_env(tmp_path)
170
+
171
+ cfg = HatchCppVcpkgConfiguration(vcpkg_triplet="x64-windows-static-md")
172
+ commands = cfg.generate(None)
173
+
174
+ assert r"vcpkg\bootstrap-vcpkg.bat" in commands
175
+ assert r"vcpkg\vcpkg.exe install --triplet x64-windows-static-md" in commands
176
+
156
177
  def test_generate_skips_clone_when_vcpkg_root_exists(self, tmp_path, monkeypatch):
157
178
  monkeypatch.chdir(tmp_path)
158
179
  self._make_vcpkg_env(tmp_path)
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from os import environ
4
4
  from pathlib import Path
5
5
  from sys import version_info
6
- from typing import Any, Dict, Optional, Union
6
+ from typing import Any
7
7
 
8
8
  from pydantic import BaseModel, Field
9
9
 
@@ -23,17 +23,17 @@ DefaultMSVCGenerator = {
23
23
 
24
24
 
25
25
  class HatchCppCmakeConfiguration(BaseModel):
26
- root: Optional[Path] = None
26
+ root: Path | None = None
27
27
  build: Path = Field(default_factory=lambda: Path("build"))
28
- install: Optional[Path] = Field(default=None)
28
+ install: Path | None = Field(default=None)
29
29
 
30
- cmake_arg_prefix: Optional[str] = Field(default=None)
31
- cmake_args: Dict[str, str] = Field(default_factory=dict)
32
- cmake_env_args: Dict[Platform, Dict[str, str]] = Field(default_factory=dict)
30
+ cmake_arg_prefix: str | None = Field(default=None)
31
+ cmake_args: dict[str, str] = Field(default_factory=dict)
32
+ cmake_env_args: dict[Platform, dict[str, str]] = Field(default_factory=dict)
33
33
 
34
- include_flags: Optional[Dict[str, Union[str, int, float, bool]]] = Field(default=None)
34
+ include_flags: dict[str, str | int | float | bool] | None = Field(default=None)
35
35
 
36
- def generate(self, config) -> Dict[str, Any]:
36
+ def generate(self, config) -> dict[str, Any]:
37
37
  commands = []
38
38
 
39
39
  # Derive prefix
@@ -6,20 +6,20 @@ from re import match
6
6
  from shutil import which
7
7
  from sys import base_exec_prefix, exec_prefix, executable, platform as sys_platform
8
8
  from sysconfig import get_config_var, get_path
9
- from typing import Any, List, Literal, Optional
9
+ from typing import Any, Literal
10
10
 
11
11
  from pydantic import AliasChoices, BaseModel, Field, field_validator, model_validator
12
12
 
13
13
  __all__ = (
14
+ "Binding",
14
15
  "BuildType",
15
16
  "CompilerToolchain",
16
- "Toolchain",
17
+ "HatchCppLibrary",
18
+ "HatchCppPlatform",
17
19
  "Language",
18
- "Binding",
19
20
  "Platform",
20
21
  "PlatformDefaults",
21
- "HatchCppLibrary",
22
- "HatchCppPlatform",
22
+ "Toolchain",
23
23
  "_normalize_rpath",
24
24
  )
25
25
 
@@ -41,63 +41,62 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
41
41
  """A C++ library."""
42
42
 
43
43
  name: str
44
- sources: List[str]
44
+ sources: list[str]
45
45
  language: Language = "c++"
46
46
 
47
47
  binding: Binding = "cpython"
48
- std: Optional[str] = None
48
+ std: str | None = None
49
49
 
50
- include_dirs: List[str] = Field(default_factory=list, alias=AliasChoices("include_dirs", "include-dirs"))
51
- include_dirs_linux: List[str] = Field(default_factory=list, alias=AliasChoices("include_dirs_linux", "include-dirs-linux"))
52
- include_dirs_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("include_dirs_darwin", "include-dirs-darwin"))
53
- include_dirs_win32: List[str] = Field(default_factory=list, alias=AliasChoices("include_dirs_win32", "include-dirs-win32"))
50
+ include_dirs: list[str] = Field(default_factory=list, alias=AliasChoices("include_dirs", "include-dirs"))
51
+ include_dirs_linux: list[str] = Field(default_factory=list, alias=AliasChoices("include_dirs_linux", "include-dirs-linux"))
52
+ include_dirs_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("include_dirs_darwin", "include-dirs-darwin"))
53
+ include_dirs_win32: list[str] = Field(default_factory=list, alias=AliasChoices("include_dirs_win32", "include-dirs-win32"))
54
54
 
55
- library_dirs: List[str] = Field(default_factory=list, alias=AliasChoices("library_dirs", "library-dirs"))
56
- library_dirs_linux: List[str] = Field(default_factory=list, alias=AliasChoices("library_dirs_linux", "library-dirs-linux"))
57
- library_dirs_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("library_dirs_darwin", "library-dirs-darwin"))
58
- library_dirs_win32: List[str] = Field(default_factory=list, alias=AliasChoices("library_dirs_win32", "library-dirs-win32"))
55
+ library_dirs: list[str] = Field(default_factory=list, alias=AliasChoices("library_dirs", "library-dirs"))
56
+ library_dirs_linux: list[str] = Field(default_factory=list, alias=AliasChoices("library_dirs_linux", "library-dirs-linux"))
57
+ library_dirs_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("library_dirs_darwin", "library-dirs-darwin"))
58
+ library_dirs_win32: list[str] = Field(default_factory=list, alias=AliasChoices("library_dirs_win32", "library-dirs-win32"))
59
59
 
60
- libraries: List[str] = Field(default_factory=list)
61
- libraries_linux: List[str] = Field(default_factory=list, alias=AliasChoices("libraries_linux", "libraries-linux"))
62
- libraries_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("libraries_darwin", "libraries-darwin"))
63
- libraries_win32: List[str] = Field(default_factory=list, alias=AliasChoices("libraries_win32", "libraries-win32"))
60
+ libraries: list[str] = Field(default_factory=list)
61
+ libraries_linux: list[str] = Field(default_factory=list, alias=AliasChoices("libraries_linux", "libraries-linux"))
62
+ libraries_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("libraries_darwin", "libraries-darwin"))
63
+ libraries_win32: list[str] = Field(default_factory=list, alias=AliasChoices("libraries_win32", "libraries-win32"))
64
64
 
65
- extra_compile_args: List[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args", "extra-compile-args"))
66
- extra_compile_args_linux: List[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args_linux", "extra-compile-args-linux"))
67
- extra_compile_args_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args_darwin", "extra-compile-args-darwin"))
68
- extra_compile_args_win32: List[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args_win32", "extra-compile-args-win32"))
65
+ extra_compile_args: list[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args", "extra-compile-args"))
66
+ extra_compile_args_linux: list[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args_linux", "extra-compile-args-linux"))
67
+ extra_compile_args_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args_darwin", "extra-compile-args-darwin"))
68
+ extra_compile_args_win32: list[str] = Field(default_factory=list, alias=AliasChoices("extra_compile_args_win32", "extra-compile-args-win32"))
69
69
 
70
- extra_link_args: List[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args", "extra-link-args"))
71
- extra_link_args_linux: List[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args_linux", "extra-link-args-linux"))
72
- extra_link_args_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args_darwin", "extra-link-args-darwin"))
73
- extra_link_args_win32: List[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args_win32", "extra-link-args-win32"))
70
+ extra_link_args: list[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args", "extra-link-args"))
71
+ extra_link_args_linux: list[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args_linux", "extra-link-args-linux"))
72
+ extra_link_args_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args_darwin", "extra-link-args-darwin"))
73
+ extra_link_args_win32: list[str] = Field(default_factory=list, alias=AliasChoices("extra_link_args_win32", "extra-link-args-win32"))
74
74
 
75
- extra_objects: List[str] = Field(default_factory=list, alias=AliasChoices("extra_objects", "extra-objects"))
76
- extra_objects_linux: List[str] = Field(default_factory=list, alias=AliasChoices("extra_objects_linux", "extra-objects-linux"))
77
- extra_objects_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("extra_objects_darwin", "extra-objects-darwin"))
78
- extra_objects_win32: List[str] = Field(default_factory=list, alias=AliasChoices("extra_objects_win32", "extra-objects-win32"))
75
+ extra_objects: list[str] = Field(default_factory=list, alias=AliasChoices("extra_objects", "extra-objects"))
76
+ extra_objects_linux: list[str] = Field(default_factory=list, alias=AliasChoices("extra_objects_linux", "extra-objects-linux"))
77
+ extra_objects_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("extra_objects_darwin", "extra-objects-darwin"))
78
+ extra_objects_win32: list[str] = Field(default_factory=list, alias=AliasChoices("extra_objects_win32", "extra-objects-win32"))
79
79
 
80
- define_macros: List[str] = Field(default_factory=list, alias=AliasChoices("define_macros", "define-macros"))
81
- define_macros_linux: List[str] = Field(default_factory=list, alias=AliasChoices("define_macros_linux", "define-macros-linux"))
82
- define_macros_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("define_macros_darwin", "define-macros-darwin"))
83
- define_macros_win32: List[str] = Field(default_factory=list, alias=AliasChoices("define_macros_win32", "define-macros-win32"))
80
+ define_macros: list[str] = Field(default_factory=list, alias=AliasChoices("define_macros", "define-macros"))
81
+ define_macros_linux: list[str] = Field(default_factory=list, alias=AliasChoices("define_macros_linux", "define-macros-linux"))
82
+ define_macros_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("define_macros_darwin", "define-macros-darwin"))
83
+ define_macros_win32: list[str] = Field(default_factory=list, alias=AliasChoices("define_macros_win32", "define-macros-win32"))
84
84
 
85
- undef_macros: List[str] = Field(default_factory=list, alias=AliasChoices("undef_macros", "undef-macros"))
86
- undef_macros_linux: List[str] = Field(default_factory=list, alias=AliasChoices("undef_macros_linux", "undef-macros-linux"))
87
- undef_macros_darwin: List[str] = Field(default_factory=list, alias=AliasChoices("undef_macros_darwin", "undef-macros-darwin"))
88
- undef_macros_win32: List[str] = Field(default_factory=list, alias=AliasChoices("undef_macros_win32", "undef-macros-win32"))
85
+ undef_macros: list[str] = Field(default_factory=list, alias=AliasChoices("undef_macros", "undef-macros"))
86
+ undef_macros_linux: list[str] = Field(default_factory=list, alias=AliasChoices("undef_macros_linux", "undef-macros-linux"))
87
+ undef_macros_darwin: list[str] = Field(default_factory=list, alias=AliasChoices("undef_macros_darwin", "undef-macros-darwin"))
88
+ undef_macros_win32: list[str] = Field(default_factory=list, alias=AliasChoices("undef_macros_win32", "undef-macros-win32"))
89
89
 
90
- export_symbols: List[str] = Field(default_factory=list, alias=AliasChoices("export_symbols", "export-symbols"))
91
- depends: List[str] = Field(default_factory=list)
90
+ export_symbols: list[str] = Field(default_factory=list, alias=AliasChoices("export_symbols", "export-symbols"))
91
+ depends: list[str] = Field(default_factory=list)
92
92
 
93
- py_limited_api: Optional[str] = Field(default="", alias=AliasChoices("py_limited_api", "py-limited-api"))
93
+ py_limited_api: str | None = Field(default="", alias=AliasChoices("py_limited_api", "py-limited-api"))
94
94
 
95
95
  @field_validator("py_limited_api", mode="before")
96
96
  @classmethod
97
97
  def check_py_limited_api(cls, value: Any) -> Any:
98
- if value:
99
- if not match(r"cp3\d", value):
100
- raise ValueError("py-limited-api must be in the form of cp3X")
98
+ if value and not match(r"cp3\d", value):
99
+ raise ValueError("py-limited-api must be in the form of cp3X")
101
100
  return value
102
101
 
103
102
  def get_qualified_name(self, platform):
@@ -122,7 +121,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
122
121
  raise ValueError("Generic binding can not support Py_LIMITED_API")
123
122
  return self
124
123
 
125
- def get_effective_link_args(self, platform: Platform) -> List[str]:
124
+ def get_effective_link_args(self, platform: Platform) -> list[str]:
126
125
  """Get link args merged with platform-specific link args."""
127
126
  args = list(self.extra_link_args)
128
127
  if platform == "linux":
@@ -133,7 +132,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
133
132
  args.extend(self.extra_link_args_win32)
134
133
  return args
135
134
 
136
- def get_effective_include_dirs(self, platform: Platform) -> List[str]:
135
+ def get_effective_include_dirs(self, platform: Platform) -> list[str]:
137
136
  """Get include dirs merged with platform-specific include dirs."""
138
137
  dirs = list(self.include_dirs)
139
138
  if platform == "linux":
@@ -144,7 +143,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
144
143
  dirs.extend(self.include_dirs_win32)
145
144
  return dirs
146
145
 
147
- def get_effective_library_dirs(self, platform: Platform) -> List[str]:
146
+ def get_effective_library_dirs(self, platform: Platform) -> list[str]:
148
147
  """Get library dirs merged with platform-specific library dirs."""
149
148
  dirs = list(self.library_dirs)
150
149
  if platform == "linux":
@@ -155,7 +154,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
155
154
  dirs.extend(self.library_dirs_win32)
156
155
  return dirs
157
156
 
158
- def get_effective_libraries(self, platform: Platform) -> List[str]:
157
+ def get_effective_libraries(self, platform: Platform) -> list[str]:
159
158
  """Get libraries merged with platform-specific libraries."""
160
159
  libs = list(self.libraries)
161
160
  if platform == "linux":
@@ -166,7 +165,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
166
165
  libs.extend(self.libraries_win32)
167
166
  return libs
168
167
 
169
- def get_effective_compile_args(self, platform: Platform) -> List[str]:
168
+ def get_effective_compile_args(self, platform: Platform) -> list[str]:
170
169
  """Get compile args merged with platform-specific compile args."""
171
170
  args = list(self.extra_compile_args)
172
171
  if platform == "linux":
@@ -177,7 +176,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
177
176
  args.extend(self.extra_compile_args_win32)
178
177
  return args
179
178
 
180
- def get_effective_extra_objects(self, platform: Platform) -> List[str]:
179
+ def get_effective_extra_objects(self, platform: Platform) -> list[str]:
181
180
  """Get extra objects merged with platform-specific extra objects."""
182
181
  objs = list(self.extra_objects)
183
182
  if platform == "linux":
@@ -188,7 +187,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
188
187
  objs.extend(self.extra_objects_win32)
189
188
  return objs
190
189
 
191
- def get_effective_define_macros(self, platform: Platform) -> List[str]:
190
+ def get_effective_define_macros(self, platform: Platform) -> list[str]:
192
191
  """Get define macros merged with platform-specific define macros."""
193
192
  macros = list(self.define_macros)
194
193
  if platform == "linux":
@@ -199,7 +198,7 @@ class HatchCppLibrary(BaseModel, validate_assignment=True):
199
198
  macros.extend(self.define_macros_win32)
200
199
  return macros
201
200
 
202
- def get_effective_undef_macros(self, platform: Platform) -> List[str]:
201
+ def get_effective_undef_macros(self, platform: Platform) -> list[str]:
203
202
  """Get undef macros merged with platform-specific undef macros."""
204
203
  macros = list(self.undef_macros)
205
204
  if platform == "linux":
@@ -274,12 +273,11 @@ class HatchCppPlatform(BaseModel):
274
273
  @classmethod
275
274
  def validate_model(cls, data, handler):
276
275
  model = handler(data)
277
- if which("ccache") and not model.disable_ccache:
278
- if model.toolchain in ["gcc", "clang"]:
279
- if not model.cc.startswith("ccache "):
280
- model.cc = f"ccache {model.cc}"
281
- if not model.cxx.startswith("ccache "):
282
- model.cxx = f"ccache {model.cxx}"
276
+ if which("ccache") and not model.disable_ccache and model.toolchain in ["gcc", "clang"]:
277
+ if not model.cc.startswith("ccache "):
278
+ model.cc = f"ccache {model.cc}"
279
+ if not model.cxx.startswith("ccache "):
280
+ model.cxx = f"ccache {model.cxx}"
283
281
  return model
284
282
 
285
283
  @staticmethod
@@ -316,7 +314,7 @@ class HatchCppPlatform(BaseModel):
316
314
  if not library.std:
317
315
  library.std = "c++17"
318
316
  library.sources.append(str(Path(nanobind.include_dir()).parent / "src" / "nb_combined.cpp"))
319
- effective_include_dirs.append(str((Path(nanobind.include_dir()).parent / "ext" / "robin_map" / "include")))
317
+ effective_include_dirs.append(str(Path(nanobind.include_dir()).parent / "ext" / "robin_map" / "include"))
320
318
 
321
319
  if library.py_limited_api:
322
320
  if library.binding == "pybind11":
@@ -367,20 +365,7 @@ class HatchCppPlatform(BaseModel):
367
365
  # Normalize rpath values ($ORIGIN <-> @loader_path) and escape for shell
368
366
  effective_link_args = [_normalize_rpath(arg, self.platform) for arg in effective_link_args]
369
367
 
370
- if self.toolchain == "gcc":
371
- flags += " -shared"
372
- flags += " " + " ".join(effective_link_args)
373
- flags += " " + " ".join(effective_extra_objects)
374
- flags += " " + " ".join(f"-l{lib}" for lib in effective_libraries)
375
- flags += " " + " ".join(f"-L{lib}" for lib in effective_library_dirs)
376
- flags += f" -o {library.get_qualified_name(self.platform)}"
377
- if self.platform == "darwin":
378
- flags += " -undefined dynamic_lookup"
379
- if "mold" in self.ld:
380
- flags += f" -fuse-ld={self.ld}"
381
- elif "lld" in self.ld:
382
- flags += " -fuse-ld=lld"
383
- elif self.toolchain == "clang":
368
+ if self.toolchain == "gcc" or self.toolchain == "clang":
384
369
  flags += " -shared"
385
370
  flags += " " + " ".join(effective_link_args)
386
371
  flags += " " + " ".join(effective_extra_objects)
@@ -411,7 +396,7 @@ class HatchCppPlatform(BaseModel):
411
396
  ]
412
397
  for libs_path in python_libs_paths:
413
398
  if libs_path.exists():
414
- flags += f" /LIBPATH:{str(libs_path)}"
399
+ flags += f" /LIBPATH:{libs_path!s}"
415
400
  break
416
401
  flags += " " + " ".join(f"{lib}.lib" for lib in effective_libraries)
417
402
  flags += " " + " ".join(f"/LIBPATH:{lib}" for lib in effective_library_dirs)
@@ -5,7 +5,7 @@ import subprocess
5
5
  from pathlib import Path
6
6
  from platform import machine as platform_machine
7
7
  from sys import platform as sys_platform
8
- from typing import Literal, Optional
8
+ from typing import Literal
9
9
 
10
10
  from pydantic import BaseModel, Field
11
11
 
@@ -40,7 +40,7 @@ VcpkgPlatformDefaults = {
40
40
  }
41
41
 
42
42
 
43
- def _read_vcpkg_ref_from_gitmodules(vcpkg_root: Path) -> Optional[str]:
43
+ def _read_vcpkg_ref_from_gitmodules(vcpkg_root: Path) -> str | None:
44
44
  """Read the branch/ref for vcpkg from .gitmodules if it exists.
45
45
 
46
46
  Looks for a submodule whose path matches ``vcpkg_root`` and returns
@@ -61,11 +61,11 @@ def _read_vcpkg_ref_from_gitmodules(vcpkg_root: Path) -> Optional[str]:
61
61
 
62
62
 
63
63
  class HatchCppVcpkgConfiguration(BaseModel):
64
- vcpkg: Optional[str] = Field(default="vcpkg.json")
65
- vcpkg_root: Optional[Path] = Field(default=Path("vcpkg"))
66
- vcpkg_repo: Optional[str] = Field(default="https://github.com/microsoft/vcpkg.git")
67
- vcpkg_triplet: Optional[VcpkgTriplet] = Field(default=None)
68
- vcpkg_ref: Optional[str] = Field(
64
+ vcpkg: str | None = Field(default="vcpkg.json")
65
+ vcpkg_root: Path | None = Field(default=Path("vcpkg"))
66
+ vcpkg_repo: str | None = Field(default="https://github.com/microsoft/vcpkg.git")
67
+ vcpkg_triplet: VcpkgTriplet | None = Field(default=None)
68
+ vcpkg_ref: str | None = Field(
69
69
  default=None,
70
70
  description="Branch, tag, or commit SHA to checkout after cloning vcpkg. "
71
71
  "If not set, falls back to the branch specified in .gitmodules for the vcpkg submodule.",
@@ -73,7 +73,7 @@ class HatchCppVcpkgConfiguration(BaseModel):
73
73
 
74
74
  # TODO: overlay
75
75
 
76
- def _resolve_vcpkg_ref(self) -> Optional[str]:
76
+ def _resolve_vcpkg_ref(self) -> str | None:
77
77
  """Return the ref to checkout: explicit config takes priority, then .gitmodules."""
78
78
  if self.vcpkg_ref is not None:
79
79
  return self.vcpkg_ref
@@ -87,6 +87,11 @@ class HatchCppVcpkgConfiguration(BaseModel):
87
87
  return self.vcpkg_root / "vcpkg.exe"
88
88
  return self.vcpkg_root / "vcpkg"
89
89
 
90
+ def _command_path(self, path: Path) -> str:
91
+ if sys_platform == "win32":
92
+ return str(path).replace("/", "\\")
93
+ return f"./{path}"
94
+
90
95
  def _delete_dir_command(self, path: Path) -> str:
91
96
  if sys_platform == "win32":
92
97
  return f'rmdir /s /q "{path}"'
@@ -109,7 +114,7 @@ class HatchCppVcpkgConfiguration(BaseModel):
109
114
  if ref is not None:
110
115
  commands.append(f"git -C {self.vcpkg_root} checkout {ref}")
111
116
 
112
- commands.append(f"./{self._bootstrap_script_path()}")
117
+ commands.append(self._command_path(self._bootstrap_script_path()))
113
118
  return commands
114
119
 
115
120
  def generate(self, config):
@@ -134,11 +139,11 @@ class HatchCppVcpkgConfiguration(BaseModel):
134
139
  else:
135
140
  vcpkg_executable = self._vcpkg_executable_path()
136
141
  if not vcpkg_executable.exists():
137
- commands.append(f"./{bootstrap_script}")
142
+ commands.append(self._command_path(bootstrap_script))
138
143
  elif not self._is_vcpkg_working():
139
144
  commands.append(self._delete_dir_command(vcpkg_root))
140
145
  commands.extend(self._clone_checkout_bootstrap_commands())
141
146
 
142
- commands.append(f"./{self.vcpkg_root / 'vcpkg'} install --triplet {self.vcpkg_triplet}")
147
+ commands.append(f"{self._command_path(self._vcpkg_executable_path())} install --triplet {self.vcpkg_triplet}")
143
148
 
144
149
  return commands
hatch_cpp/utils.py CHANGED
@@ -1,12 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
- from functools import lru_cache
3
+ from functools import cache
4
4
 
5
5
  from pydantic import ImportString, TypeAdapter
6
6
 
7
7
  _import_string_adapter = TypeAdapter(ImportString)
8
8
 
9
9
 
10
- @lru_cache(maxsize=None)
10
+ @cache
11
11
  def import_string(input_string: str):
12
12
  return _import_string_adapter.validate_python(input_string)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hatch-cpp
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Hatch plugin for C++ builds
5
5
  Project-URL: Repository, https://github.com/python-project-templates/hatch-cpp
6
6
  Project-URL: Homepage, https://github.com/python-project-templates/hatch-cpp
@@ -12,7 +12,6 @@ Classifier: Development Status :: 3 - Alpha
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
@@ -1,25 +1,25 @@
1
- hatch_cpp/__init__.py,sha256=QnAS8UARqj-I35tzWD70JsB-xoePWVJxNMNgBt0Y_PU,114
2
- hatch_cpp/config.py,sha256=aRmcRyrPR7LsEOBjrF9pkOM3ldiykuYRmD73CB3k9MY,4512
3
- hatch_cpp/hooks.py,sha256=SQkF5WJIgzw-8rvlTzuQvBqdP6K3fHgnh6CZOZFag50,203
4
- hatch_cpp/plugin.py,sha256=NcIDi7c9KH-_RkPeeCgWKoH5InIjw2eECswazwvGl_c,4304
5
- hatch_cpp/utils.py,sha256=lxd3U3aMYsTS6DYMc1y17MR16LzgRzv92f_xh87LSg8,297
1
+ hatch_cpp/__init__.py,sha256=obN0qecZxCCF7GZRXEfOmWIF0PaLdpwOFr04l0P5tzw,114
2
+ hatch_cpp/config.py,sha256=BlLr2hivhlp-1S6aSbJlHPWHtxMGvF0SMR-dJRPXQro,4460
3
+ hatch_cpp/hooks.py,sha256=OfcAgx6gVL0ukvpyln5OTiwhqxObJ0b4FKr850fYP3I,178
4
+ hatch_cpp/plugin.py,sha256=8Y4d6FMQocVzoNEWLbryeY1Wr_dUxQ3DJjiQHAjj4zg,4302
5
+ hatch_cpp/utils.py,sha256=dxLCyoMLC7C0trJ8mlvwA5-JzVNt2JI9JSGYcHTHBY4,275
6
6
  hatch_cpp/tests/test_hatch_build.py,sha256=q2IKTFi3Pq99UsOyL84V-C9VtFUs3ZcA9UlA8lpRW54,1553
7
7
  hatch_cpp/tests/test_platform_specific.py,sha256=SRKAojh6PkwKZnEj8SjvfFa_Dy8NSKw4R82ol8O1TZs,20126
8
- hatch_cpp/tests/test_projects.py,sha256=v05hZI9kfBCU6CpWXixyetNy92nC4Dajtxyj03lLjkQ,2168
8
+ hatch_cpp/tests/test_projects.py,sha256=WAV8OAV-4Xp4o91S1nlj9ptmpexlXEIXnfSozt0mhCI,2123
9
9
  hatch_cpp/tests/test_structs.py,sha256=zmNtAV1bojvJM6gatjDtvqrAeUpKzpfmLrzgFTZLo8U,12028
10
- hatch_cpp/tests/test_vcpkg_ref.py,sha256=wcfbFp8Tc6E2hiQPlextdno0NYrA1yljRSRUIQEj0mM,9969
10
+ hatch_cpp/tests/test_vcpkg_ref.py,sha256=1inxhiDD_QQThKe804UZ-SZkh5lcUUWjzb63ATZ9c9Y,10854
11
11
  hatch_cpp/tests/test_project_basic/pyproject.toml,sha256=eqM1UVpNmJWDfsuO18ZG_VOV9I4tAWgsM5Dhf49X8Nc,694
12
12
  hatch_cpp/tests/test_project_basic/cpp/project/basic.cpp,sha256=gQ2nmdLqIdgaqxSKvkN_vbp6Iv_pAoVIHETXPRnALb0,117
13
13
  hatch_cpp/tests/test_project_basic/cpp/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
14
14
  hatch_cpp/tests/test_project_basic/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- hatch_cpp/tests/test_project_cmake/CMakeLists.txt,sha256=OvJT0L18qH6zRm3Uw8pO6085WLY1HMvBgq6zIcFuQvU,2580
15
+ hatch_cpp/tests/test_project_cmake/CMakeLists.txt,sha256=_62H73yB-hJUCj_PiOGZUTauFB25q0h1TOQ9n855A74,2605
16
16
  hatch_cpp/tests/test_project_cmake/Makefile,sha256=Vfr65pvnktWTUeuvpMWqIxDR-7V9MT4PQAyj-WHG_pI,4357
17
17
  hatch_cpp/tests/test_project_cmake/pyproject.toml,sha256=judDNJ0qYM6-ocGXtUEHQlUzyj8GsF5qoJ-jPDsIAdA,815
18
18
  hatch_cpp/tests/test_project_cmake/cpp/project/basic.cpp,sha256=gQ2nmdLqIdgaqxSKvkN_vbp6Iv_pAoVIHETXPRnALb0,117
19
19
  hatch_cpp/tests/test_project_cmake/cpp/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
20
20
  hatch_cpp/tests/test_project_cmake/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  hatch_cpp/tests/test_project_cmake/project/include/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
22
- hatch_cpp/tests/test_project_cmake_vcpkg/CMakeLists.txt,sha256=OvJT0L18qH6zRm3Uw8pO6085WLY1HMvBgq6zIcFuQvU,2580
22
+ hatch_cpp/tests/test_project_cmake_vcpkg/CMakeLists.txt,sha256=_62H73yB-hJUCj_PiOGZUTauFB25q0h1TOQ9n855A74,2605
23
23
  hatch_cpp/tests/test_project_cmake_vcpkg/Makefile,sha256=Vfr65pvnktWTUeuvpMWqIxDR-7V9MT4PQAyj-WHG_pI,4357
24
24
  hatch_cpp/tests/test_project_cmake_vcpkg/pyproject.toml,sha256=pu9RWhm_FY7KlcdOg2nmp-obnStnPJ04jW-bxei704w,814
25
25
  hatch_cpp/tests/test_project_cmake_vcpkg/vcpkg.json,sha256=3D_Mm48_-srxYzbdHNCVO00eFLLGZfsFfL6IMcK0x3E,162
@@ -57,11 +57,11 @@ hatch_cpp/tests/test_project_pybind_vcpkg/cpp/project/basic.cpp,sha256=MT3eCSQKr
57
57
  hatch_cpp/tests/test_project_pybind_vcpkg/cpp/project/basic.hpp,sha256=LZSfCfhLY_91MBOxtnvDk7DcceO-9GhCHKpMnAjGe18,146
58
58
  hatch_cpp/tests/test_project_pybind_vcpkg/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  hatch_cpp/toolchains/__init__.py,sha256=anza4tXKxauobWMOUrxX3sEO0qs7sp6VdLXhLae3vkY,64
60
- hatch_cpp/toolchains/cmake.py,sha256=yUMw6LzmasjRiJfxN98b-E9fDxUbM0-mz-RL0O7IVag,3748
61
- hatch_cpp/toolchains/common.py,sha256=O6eb5qoo9GArI4MB4cLL1z6UnA4rbWxQ5VUIHJmbHBQ,20423
62
- hatch_cpp/toolchains/vcpkg.py,sha256=fBBModZOL49yJH8971zsOuuRPgTnmR2qvU_0AdT__DY,5233
63
- hatch_cpp-0.4.0.dist-info/METADATA,sha256=puWLBhQOtranOGnNuD83YJl2li5CHAYaYmBaPm2iYd0,9889
64
- hatch_cpp-0.4.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
65
- hatch_cpp-0.4.0.dist-info/entry_points.txt,sha256=RgXfjpD4iwomJQK5n7FnPkXzb5fOnF5v3DI5hbkgVcw,30
66
- hatch_cpp-0.4.0.dist-info/licenses/LICENSE,sha256=FWyFTpd5xXEz50QpGDtsyIv6dgR2z_dHdoab_Nq_KMw,11452
67
- hatch_cpp-0.4.0.dist-info/RECORD,,
60
+ hatch_cpp/toolchains/cmake.py,sha256=9fOGXuJ4bpkKjU789GApK59WS4iZQNQK19Q_Zq_Byb4,3709
61
+ hatch_cpp/toolchains/common.py,sha256=RoPfzuNCRWoqzpocymS_mhincOZZjKa0WVCLuckZijg,19704
62
+ hatch_cpp/toolchains/vcpkg.py,sha256=N9iG9A37VkHRswfq1Fv4WWGxdRQgPB0ALQ1iGyork3w,5410
63
+ hatch_cpp-0.4.1.dist-info/METADATA,sha256=Yzq7UrWCdfAM7d0prW2WFzT4bqVKJt_oP4fhdXGYGPw,9838
64
+ hatch_cpp-0.4.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
65
+ hatch_cpp-0.4.1.dist-info/entry_points.txt,sha256=RgXfjpD4iwomJQK5n7FnPkXzb5fOnF5v3DI5hbkgVcw,30
66
+ hatch_cpp-0.4.1.dist-info/licenses/LICENSE,sha256=FWyFTpd5xXEz50QpGDtsyIv6dgR2z_dHdoab_Nq_KMw,11452
67
+ hatch_cpp-0.4.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.30.1
2
+ Generator: hatchling 1.31.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any