hatch-cpp 0.1.8__py3-none-any.whl → 0.2.0__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 +5 -4
- hatch_cpp/config.py +101 -0
- hatch_cpp/plugin.py +5 -1
- hatch_cpp/tests/test_hatch_build.py +46 -0
- hatch_cpp/tests/test_project_cmake/pyproject.toml +1 -1
- hatch_cpp/tests/test_project_cmake_vcpkg/CMakeLists.txt +92 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/Makefile +140 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/cpp/project/basic.cpp +5 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/cpp/project/basic.hpp +17 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/project/__init__.py +0 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/project/include/project/basic.hpp +17 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/pyproject.toml +39 -0
- hatch_cpp/tests/test_project_cmake_vcpkg/vcpkg.json +8 -0
- hatch_cpp/tests/test_project_hatch_build/cpp/project/basic.cpp +2 -0
- hatch_cpp/tests/test_project_hatch_build/cpp/project/basic.hpp +7 -0
- hatch_cpp/tests/test_project_hatch_build/project/__init__.py +0 -0
- hatch_cpp/tests/test_project_hatch_build/pyproject.toml +36 -0
- hatch_cpp/tests/test_project_pybind_vcpkg/cpp/project/basic.cpp +6 -0
- hatch_cpp/tests/test_project_pybind_vcpkg/cpp/project/basic.hpp +9 -0
- hatch_cpp/tests/test_project_pybind_vcpkg/project/__init__.py +0 -0
- hatch_cpp/tests/test_project_pybind_vcpkg/pyproject.toml +35 -0
- hatch_cpp/tests/test_project_pybind_vcpkg/vcpkg.json +8 -0
- hatch_cpp/tests/test_projects.py +2 -0
- hatch_cpp/tests/test_structs.py +1 -1
- hatch_cpp/toolchains/__init__.py +3 -0
- hatch_cpp/toolchains/cmake.py +87 -0
- hatch_cpp/{structs.py → toolchains/common.py} +12 -120
- hatch_cpp/toolchains/vcpkg.py +64 -0
- {hatch_cpp-0.1.8.dist-info → hatch_cpp-0.2.0.dist-info}/METADATA +20 -6
- {hatch_cpp-0.1.8.dist-info → hatch_cpp-0.2.0.dist-info}/RECORD +33 -13
- {hatch_cpp-0.1.8.dist-info → hatch_cpp-0.2.0.dist-info}/WHEEL +0 -0
- {hatch_cpp-0.1.8.dist-info → hatch_cpp-0.2.0.dist-info}/entry_points.txt +0 -0
- {hatch_cpp-0.1.8.dist-info → hatch_cpp-0.2.0.dist-info}/licenses/LICENSE +0 -0
hatch_cpp/__init__.py
CHANGED
hatch_cpp/config.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from logging import getLogger
|
|
4
|
+
from os import system as system_call
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import List, Optional
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field, model_validator
|
|
9
|
+
|
|
10
|
+
from .toolchains import BuildType, HatchCppCmakeConfiguration, HatchCppLibrary, HatchCppPlatform, HatchCppVcpkgConfiguration, Toolchain
|
|
11
|
+
|
|
12
|
+
__all__ = (
|
|
13
|
+
"HatchCppBuildConfig",
|
|
14
|
+
"HatchCppBuildPlan",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
_log = getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HatchCppBuildConfig(BaseModel):
|
|
22
|
+
"""Build config values for Hatch C++ Builder."""
|
|
23
|
+
|
|
24
|
+
verbose: Optional[bool] = Field(default=False)
|
|
25
|
+
name: Optional[str] = Field(default=None)
|
|
26
|
+
libraries: List[HatchCppLibrary] = Field(default_factory=list)
|
|
27
|
+
cmake: Optional[HatchCppCmakeConfiguration] = Field(default=None)
|
|
28
|
+
platform: Optional[HatchCppPlatform] = Field(default_factory=HatchCppPlatform.default)
|
|
29
|
+
vcpkg: Optional[HatchCppVcpkgConfiguration] = Field(default_factory=HatchCppVcpkgConfiguration)
|
|
30
|
+
|
|
31
|
+
@model_validator(mode="wrap")
|
|
32
|
+
@classmethod
|
|
33
|
+
def validate_model(cls, data, handler):
|
|
34
|
+
if "toolchain" in data:
|
|
35
|
+
data["platform"] = HatchCppPlatform.platform_for_toolchain(data["toolchain"])
|
|
36
|
+
data.pop("toolchain")
|
|
37
|
+
elif "platform" not in data:
|
|
38
|
+
data["platform"] = HatchCppPlatform.default()
|
|
39
|
+
if "cc" in data:
|
|
40
|
+
data["platform"].cc = data["cc"]
|
|
41
|
+
data.pop("cc")
|
|
42
|
+
if "cxx" in data:
|
|
43
|
+
data["platform"].cxx = data["cxx"]
|
|
44
|
+
data.pop("cxx")
|
|
45
|
+
if "ld" in data:
|
|
46
|
+
data["platform"].ld = data["ld"]
|
|
47
|
+
data.pop("ld")
|
|
48
|
+
if "vcpkg" in data and data["vcpkg"] == "false":
|
|
49
|
+
data["vcpkg"] = None
|
|
50
|
+
model = handler(data)
|
|
51
|
+
if model.cmake and model.libraries:
|
|
52
|
+
raise ValueError("Must not provide libraries when using cmake toolchain.")
|
|
53
|
+
return model
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class HatchCppBuildPlan(HatchCppBuildConfig):
|
|
57
|
+
build_type: BuildType = "release"
|
|
58
|
+
commands: List[str] = Field(default_factory=list)
|
|
59
|
+
|
|
60
|
+
_active_toolchains: List[Toolchain] = []
|
|
61
|
+
|
|
62
|
+
def generate(self):
|
|
63
|
+
self.commands = []
|
|
64
|
+
|
|
65
|
+
# Evaluate toolchains
|
|
66
|
+
if self.vcpkg and Path(self.vcpkg.vcpkg).exists():
|
|
67
|
+
self._active_toolchains.append("vcpkg")
|
|
68
|
+
if self.libraries:
|
|
69
|
+
self._active_toolchains.append("vanilla")
|
|
70
|
+
elif self.cmake:
|
|
71
|
+
self._active_toolchains.append("cmake")
|
|
72
|
+
|
|
73
|
+
# Collect toolchain commands
|
|
74
|
+
if "vcpkg" in self._active_toolchains:
|
|
75
|
+
self.commands.extend(self.vcpkg.generate(self))
|
|
76
|
+
|
|
77
|
+
if "vanilla" in self._active_toolchains:
|
|
78
|
+
if "vcpkg" in self._active_toolchains:
|
|
79
|
+
_log.warning("vcpkg toolchain is active; ensure that your compiler is configured to use vcpkg includes and libs.")
|
|
80
|
+
|
|
81
|
+
for library in self.libraries:
|
|
82
|
+
compile_flags = self.platform.get_compile_flags(library, self.build_type)
|
|
83
|
+
link_flags = self.platform.get_link_flags(library, self.build_type)
|
|
84
|
+
self.commands.append(
|
|
85
|
+
f"{self.platform.cc if library.language == 'c' else self.platform.cxx} {' '.join(library.sources)} {compile_flags} {link_flags}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
if "cmake" in self._active_toolchains:
|
|
89
|
+
self.commands.extend(self.cmake.generate(self))
|
|
90
|
+
|
|
91
|
+
return self.commands
|
|
92
|
+
|
|
93
|
+
def execute(self):
|
|
94
|
+
for command in self.commands:
|
|
95
|
+
system_call(command)
|
|
96
|
+
return self.commands
|
|
97
|
+
|
|
98
|
+
def cleanup(self):
|
|
99
|
+
if self.platform.platform == "win32":
|
|
100
|
+
for temp_obj in Path(".").glob("*.obj"):
|
|
101
|
+
temp_obj.unlink()
|
hatch_cpp/plugin.py
CHANGED
|
@@ -7,9 +7,10 @@ from platform import machine as platform_machine
|
|
|
7
7
|
from sys import platform as sys_platform, version_info
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
|
+
from hatch_build import parse_extra_args_model
|
|
10
11
|
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
11
12
|
|
|
12
|
-
from .
|
|
13
|
+
from .config import HatchCppBuildConfig, HatchCppBuildPlan
|
|
13
14
|
from .utils import import_string
|
|
14
15
|
|
|
15
16
|
__all__ = ("HatchCppBuildHook",)
|
|
@@ -52,6 +53,9 @@ class HatchCppBuildHook(BuildHookInterface[HatchCppBuildConfig]):
|
|
|
52
53
|
# Instantiate builder
|
|
53
54
|
build_plan = build_plan_class(**config.model_dump())
|
|
54
55
|
|
|
56
|
+
# Parse override args
|
|
57
|
+
parse_extra_args_model(build_plan)
|
|
58
|
+
|
|
55
59
|
# Generate commands
|
|
56
60
|
build_plan.generate()
|
|
57
61
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from os import listdir
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from shutil import rmtree
|
|
4
|
+
from subprocess import check_call
|
|
5
|
+
from sys import modules, path, platform
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestHatchBuild:
|
|
9
|
+
def test_hatch_build(self):
|
|
10
|
+
project = "test_project_hatch_build"
|
|
11
|
+
|
|
12
|
+
rmtree(f"hatch_cpp/tests/{project}/project/extension.so", ignore_errors=True)
|
|
13
|
+
rmtree(f"hatch_cpp/tests/{project}/project/extension.pyd", ignore_errors=True)
|
|
14
|
+
modules.pop("project", None)
|
|
15
|
+
modules.pop("project.extension", None)
|
|
16
|
+
|
|
17
|
+
# compile
|
|
18
|
+
check_call(
|
|
19
|
+
[
|
|
20
|
+
"hatch-build",
|
|
21
|
+
"--hooks-only",
|
|
22
|
+
"--",
|
|
23
|
+
"--libraries.0.name=project/extension",
|
|
24
|
+
"--libraries.0.sources=cpp/project/basic.cpp",
|
|
25
|
+
"--libraries.0.include-dirs=cpp",
|
|
26
|
+
"--libraries.0.binding=nanobind",
|
|
27
|
+
],
|
|
28
|
+
cwd=f"hatch_cpp/tests/{project}",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# assert built
|
|
32
|
+
|
|
33
|
+
if project == "test_project_limited_api" and platform != "win32":
|
|
34
|
+
assert "extension.abi3.so" in listdir(f"hatch_cpp/tests/{project}/project")
|
|
35
|
+
else:
|
|
36
|
+
if platform == "win32":
|
|
37
|
+
assert "extension.pyd" in listdir(f"hatch_cpp/tests/{project}/project")
|
|
38
|
+
else:
|
|
39
|
+
assert "extension.so" in listdir(f"hatch_cpp/tests/{project}/project")
|
|
40
|
+
|
|
41
|
+
# import
|
|
42
|
+
here = Path(__file__).parent / project
|
|
43
|
+
path.insert(0, str(here))
|
|
44
|
+
import project.extension
|
|
45
|
+
|
|
46
|
+
assert project.extension.hello() == "A string"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.20.0)
|
|
2
|
+
project(hatch-cpp-test-project-basic VERSION "0.1.0")
|
|
3
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
4
|
+
include(CheckCCompilerFlag)
|
|
5
|
+
include(CheckLinkerFlag)
|
|
6
|
+
|
|
7
|
+
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
|
8
|
+
set(WIN32 ON)
|
|
9
|
+
set(MACOS OFF)
|
|
10
|
+
set(LINUX OFF)
|
|
11
|
+
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|
12
|
+
set(WIN32 OFF)
|
|
13
|
+
set(MACOS ON)
|
|
14
|
+
set(LINUX OFF)
|
|
15
|
+
else()
|
|
16
|
+
set(WIN32 OFF)
|
|
17
|
+
set(MACOS OFF)
|
|
18
|
+
set(LINUX ON)
|
|
19
|
+
endif()
|
|
20
|
+
|
|
21
|
+
option(CMAKE_BUILD_TYPE "Release/Debug build" RELEASE)
|
|
22
|
+
option(HATCH_CPP_TEST_PROJECT_BASIC_BUILD_TESTS "Build tests" OFF)
|
|
23
|
+
option(HATCH_CPP_TEST_PROJECT_BASIC_MANYLINUX "Build for python's manylinux setup" OFF)
|
|
24
|
+
|
|
25
|
+
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
|
|
26
|
+
|
|
27
|
+
set(BUILD_SHARED_LIBS TRUE)
|
|
28
|
+
set(CMAKE_MACOSX_RPATH TRUE)
|
|
29
|
+
set(CMAKE_SKIP_RPATH FALSE)
|
|
30
|
+
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
|
31
|
+
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
|
32
|
+
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|
33
|
+
set(CMAKE_INSTALL_NAME_DIR "@rpath")
|
|
34
|
+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
35
|
+
|
|
36
|
+
string(REGEX REPLACE "[ ]*-O[^ ]+[ ]*" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
37
|
+
string(REGEX REPLACE "[ ]*-Wl,-O2 -Wl,[^ ]+[ ]*" " " CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
|
38
|
+
string(REGEX REPLACE "[ ]*-Wl,-O2 -Wl,[^ ]+[ ]*" " " CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if(MACOS)
|
|
42
|
+
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
|
43
|
+
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
|
44
|
+
set(CMAKE_USE_WIN32_THREADS_INIT 0)
|
|
45
|
+
set(CMAKE_USE_PTHREADS_INIT 1)
|
|
46
|
+
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
47
|
+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup")
|
|
48
|
+
endif()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
if(MACOS)
|
|
52
|
+
set(CMAKE_INSTALL_RPATH "@loader_path/")
|
|
53
|
+
elseif(LINUX)
|
|
54
|
+
set(CMAKE_INSTALL_RPATH "\$ORIGIN")
|
|
55
|
+
endif()
|
|
56
|
+
|
|
57
|
+
if(WIN32)
|
|
58
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj")
|
|
59
|
+
foreach(warning 4244 4251 4267 4275 4290 4786 4305 4996)
|
|
60
|
+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd${warning}")
|
|
61
|
+
endforeach(warning)
|
|
62
|
+
else()
|
|
63
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
|
|
64
|
+
-g \
|
|
65
|
+
-Wall \
|
|
66
|
+
-Werror \
|
|
67
|
+
-Wno-deprecated-declarations \
|
|
68
|
+
-Wno-deprecated \
|
|
69
|
+
")
|
|
70
|
+
endif()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
find_package(Python ${CSP_PYTHON_VERSION} EXACT REQUIRED COMPONENTS Interpreter Development.Module)
|
|
74
|
+
link_directories(${Python_LIBRARY_DIRS})
|
|
75
|
+
include_directories(${Python_INCLUDE_DIRS})
|
|
76
|
+
|
|
77
|
+
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
|
78
|
+
if(NOT WIN32)
|
|
79
|
+
set(CMAKE_SHARED_LIBRARY_SUFFIX .so)
|
|
80
|
+
else()
|
|
81
|
+
set(CMAKE_SHARED_LIBRARY_SUFFIX .pyd)
|
|
82
|
+
endif()
|
|
83
|
+
|
|
84
|
+
include_directories("${CMAKE_SOURCE_DIR}/cpp")
|
|
85
|
+
|
|
86
|
+
add_library(extension SHARED cpp/project/basic.cpp)
|
|
87
|
+
set_target_properties(extension PROPERTIES PUBLIC_HEADER cpp/project/basic.hpp)
|
|
88
|
+
install(TARGETS extension
|
|
89
|
+
PUBLIC_HEADER DESTINATION project/include/project
|
|
90
|
+
RUNTIME DESTINATION project/
|
|
91
|
+
LIBRARY DESTINATION project/
|
|
92
|
+
)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# CMAKE generated file: DO NOT EDIT!
|
|
2
|
+
# Generated by "Unix Makefiles" Generator, CMake Version 3.31
|
|
3
|
+
|
|
4
|
+
# Default target executed when no arguments are given to make.
|
|
5
|
+
default_target: all
|
|
6
|
+
.PHONY : default_target
|
|
7
|
+
|
|
8
|
+
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
|
|
9
|
+
.NOTPARALLEL:
|
|
10
|
+
|
|
11
|
+
#=============================================================================
|
|
12
|
+
# Special targets provided by cmake.
|
|
13
|
+
|
|
14
|
+
# Disable implicit rules so canonical targets will work.
|
|
15
|
+
.SUFFIXES:
|
|
16
|
+
|
|
17
|
+
# Disable VCS-based implicit rules.
|
|
18
|
+
% : %,v
|
|
19
|
+
|
|
20
|
+
# Disable VCS-based implicit rules.
|
|
21
|
+
% : RCS/%
|
|
22
|
+
|
|
23
|
+
# Disable VCS-based implicit rules.
|
|
24
|
+
% : RCS/%,v
|
|
25
|
+
|
|
26
|
+
# Disable VCS-based implicit rules.
|
|
27
|
+
% : SCCS/s.%
|
|
28
|
+
|
|
29
|
+
# Disable VCS-based implicit rules.
|
|
30
|
+
% : s.%
|
|
31
|
+
|
|
32
|
+
.SUFFIXES: .hpux_make_needs_suffix_list
|
|
33
|
+
|
|
34
|
+
# Command-line flag to silence nested $(MAKE).
|
|
35
|
+
$(VERBOSE)MAKESILENT = -s
|
|
36
|
+
|
|
37
|
+
#Suppress display of executed commands.
|
|
38
|
+
$(VERBOSE).SILENT:
|
|
39
|
+
|
|
40
|
+
# A target that is always out of date.
|
|
41
|
+
cmake_force:
|
|
42
|
+
.PHONY : cmake_force
|
|
43
|
+
|
|
44
|
+
#=============================================================================
|
|
45
|
+
# Set environment variables for the build.
|
|
46
|
+
|
|
47
|
+
# The shell in which to execute make rules.
|
|
48
|
+
SHELL = /bin/sh
|
|
49
|
+
|
|
50
|
+
# The CMake executable.
|
|
51
|
+
CMAKE_COMMAND = /opt/homebrew/bin/cmake
|
|
52
|
+
|
|
53
|
+
# The command to remove a file.
|
|
54
|
+
RM = /opt/homebrew/bin/cmake -E rm -f
|
|
55
|
+
|
|
56
|
+
# Escaping for special characters.
|
|
57
|
+
EQUALS = =
|
|
58
|
+
|
|
59
|
+
# The top-level source directory on which CMake was run.
|
|
60
|
+
CMAKE_SOURCE_DIR = /Users/timkpaine/Developer/projects/templates/hatch-cpp/hatch_cpp/tests/test_project_cmake
|
|
61
|
+
|
|
62
|
+
# The top-level build directory on which CMake was run.
|
|
63
|
+
CMAKE_BINARY_DIR = /Users/timkpaine/Developer/projects/templates/hatch-cpp/hatch_cpp/tests/test_project_cmake
|
|
64
|
+
|
|
65
|
+
#=============================================================================
|
|
66
|
+
# Targets provided globally by CMake.
|
|
67
|
+
|
|
68
|
+
# Special rule for the target edit_cache
|
|
69
|
+
edit_cache:
|
|
70
|
+
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake cache editor..."
|
|
71
|
+
/opt/homebrew/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
|
72
|
+
.PHONY : edit_cache
|
|
73
|
+
|
|
74
|
+
# Special rule for the target edit_cache
|
|
75
|
+
edit_cache/fast: edit_cache
|
|
76
|
+
.PHONY : edit_cache/fast
|
|
77
|
+
|
|
78
|
+
# Special rule for the target rebuild_cache
|
|
79
|
+
rebuild_cache:
|
|
80
|
+
@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..."
|
|
81
|
+
/opt/homebrew/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
|
82
|
+
.PHONY : rebuild_cache
|
|
83
|
+
|
|
84
|
+
# Special rule for the target rebuild_cache
|
|
85
|
+
rebuild_cache/fast: rebuild_cache
|
|
86
|
+
.PHONY : rebuild_cache/fast
|
|
87
|
+
|
|
88
|
+
# The main all target
|
|
89
|
+
all: cmake_check_build_system
|
|
90
|
+
$(CMAKE_COMMAND) -E cmake_progress_start /Users/timkpaine/Developer/projects/templates/hatch-cpp/hatch_cpp/tests/test_project_cmake/CMakeFiles /Users/timkpaine/Developer/projects/templates/hatch-cpp/hatch_cpp/tests/test_project_cmake//CMakeFiles/progress.marks
|
|
91
|
+
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
|
|
92
|
+
$(CMAKE_COMMAND) -E cmake_progress_start /Users/timkpaine/Developer/projects/templates/hatch-cpp/hatch_cpp/tests/test_project_cmake/CMakeFiles 0
|
|
93
|
+
.PHONY : all
|
|
94
|
+
|
|
95
|
+
# The main clean target
|
|
96
|
+
clean:
|
|
97
|
+
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean
|
|
98
|
+
.PHONY : clean
|
|
99
|
+
|
|
100
|
+
# The main clean target
|
|
101
|
+
clean/fast: clean
|
|
102
|
+
.PHONY : clean/fast
|
|
103
|
+
|
|
104
|
+
# Prepare targets for installation.
|
|
105
|
+
preinstall: all
|
|
106
|
+
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
|
|
107
|
+
.PHONY : preinstall
|
|
108
|
+
|
|
109
|
+
# Prepare targets for installation.
|
|
110
|
+
preinstall/fast:
|
|
111
|
+
$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
|
|
112
|
+
.PHONY : preinstall/fast
|
|
113
|
+
|
|
114
|
+
# clear depends
|
|
115
|
+
depend:
|
|
116
|
+
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
|
|
117
|
+
.PHONY : depend
|
|
118
|
+
|
|
119
|
+
# Help Target
|
|
120
|
+
help:
|
|
121
|
+
@echo "The following are some of the valid targets for this Makefile:"
|
|
122
|
+
@echo "... all (the default if no target is provided)"
|
|
123
|
+
@echo "... clean"
|
|
124
|
+
@echo "... depend"
|
|
125
|
+
@echo "... edit_cache"
|
|
126
|
+
@echo "... rebuild_cache"
|
|
127
|
+
.PHONY : help
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
#=============================================================================
|
|
132
|
+
# Special targets to cleanup operation of make.
|
|
133
|
+
|
|
134
|
+
# Special rule to run CMake to check the build system integrity.
|
|
135
|
+
# No rule that depends on this can have commands that come from listfiles
|
|
136
|
+
# because they might be regenerated.
|
|
137
|
+
cmake_check_build_system:
|
|
138
|
+
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
|
|
139
|
+
.PHONY : cmake_check_build_system
|
|
140
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "Python.h"
|
|
3
|
+
|
|
4
|
+
PyObject* hello(PyObject*, PyObject*);
|
|
5
|
+
|
|
6
|
+
static PyMethodDef extension_methods[] = {
|
|
7
|
+
{"hello", (PyCFunction)hello, METH_NOARGS},
|
|
8
|
+
{nullptr, nullptr, 0, nullptr}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
static PyModuleDef extension_module = {
|
|
12
|
+
PyModuleDef_HEAD_INIT, "extension", "extension", -1, extension_methods};
|
|
13
|
+
|
|
14
|
+
PyMODINIT_FUNC PyInit_extension(void) {
|
|
15
|
+
Py_Initialize();
|
|
16
|
+
return PyModule_Create(&extension_module);
|
|
17
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "Python.h"
|
|
3
|
+
|
|
4
|
+
PyObject* hello(PyObject*, PyObject*);
|
|
5
|
+
|
|
6
|
+
static PyMethodDef extension_methods[] = {
|
|
7
|
+
{"hello", (PyCFunction)hello, METH_NOARGS},
|
|
8
|
+
{nullptr, nullptr, 0, nullptr}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
static PyModuleDef extension_module = {
|
|
12
|
+
PyModuleDef_HEAD_INIT, "extension", "extension", -1, extension_methods};
|
|
13
|
+
|
|
14
|
+
PyMODINIT_FUNC PyInit_extension(void) {
|
|
15
|
+
Py_Initialize();
|
|
16
|
+
return PyModule_Create(&extension_module);
|
|
17
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.20"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "hatch-cpp-test-project-basic"
|
|
7
|
+
description = "Basic test project for hatch-cpp"
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"hatchling>=1.20",
|
|
12
|
+
"hatch-cpp",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.hatch.build]
|
|
16
|
+
artifacts = [
|
|
17
|
+
"project/*.dll",
|
|
18
|
+
"project/*.dylib",
|
|
19
|
+
"project/*.so",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[tool.hatch.build.sources]
|
|
23
|
+
src = "/"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.sdist]
|
|
26
|
+
packages = ["project"]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["project"]
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.hooks.hatch-cpp]
|
|
32
|
+
verbose = true
|
|
33
|
+
|
|
34
|
+
[tool.hatch.build.hooks.hatch-cpp.cmake]
|
|
35
|
+
root = "CMakeLists.txt"
|
|
36
|
+
cmake_args = {"BUILD_TESTS" = "OFF"}
|
|
37
|
+
include_flags = {"python_version" = true}
|
|
38
|
+
[tool.hatch.build.hooks.hatch-cpp.cmake.cmake_env_args]
|
|
39
|
+
linux = {"MANYLINUX" = "ON"}
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.20"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "hatch-cpp-test-project-nanobind"
|
|
7
|
+
description = "Basic test project for hatch-cpp"
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"hatchling>=1.20",
|
|
12
|
+
"hatch-cpp",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.hatch.build]
|
|
16
|
+
artifacts = [
|
|
17
|
+
"project/*.dll",
|
|
18
|
+
"project/*.dylib",
|
|
19
|
+
"project/*.so",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[tool.hatch.build.sources]
|
|
23
|
+
src = "/"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.sdist]
|
|
26
|
+
packages = ["project"]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["project"]
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.hooks.hatch-cpp]
|
|
32
|
+
verbose = true
|
|
33
|
+
libraries = [
|
|
34
|
+
# {name = "project/extension", sources = ["cpp/project/basic.cpp"], include-dirs = ["cpp"], binding = "nanobind"},
|
|
35
|
+
{name = "wrong", sources = ["wrong"], include-dirs = ["wrong"], binding = "generic"},
|
|
36
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.20"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "hatch-cpp-test-project-pybind"
|
|
7
|
+
description = "Basic test project for hatch-cpp"
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"hatchling>=1.20",
|
|
12
|
+
"hatch-cpp",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.hatch.build]
|
|
16
|
+
artifacts = [
|
|
17
|
+
"project/*.dll",
|
|
18
|
+
"project/*.dylib",
|
|
19
|
+
"project/*.so",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[tool.hatch.build.sources]
|
|
23
|
+
src = "/"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.sdist]
|
|
26
|
+
packages = ["project"]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["project"]
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.hooks.hatch-cpp]
|
|
32
|
+
verbose = true
|
|
33
|
+
libraries = [
|
|
34
|
+
{name = "project/extension", sources = ["cpp/project/basic.cpp"], include-dirs = ["cpp"], binding="pybind11"},
|
|
35
|
+
]
|
hatch_cpp/tests/test_projects.py
CHANGED
|
@@ -16,9 +16,11 @@ class TestProject:
|
|
|
16
16
|
"test_project_override_classes",
|
|
17
17
|
"test_project_override_toolchain",
|
|
18
18
|
"test_project_pybind",
|
|
19
|
+
"test_project_pybind_vcpkg",
|
|
19
20
|
"test_project_nanobind",
|
|
20
21
|
"test_project_limited_api",
|
|
21
22
|
"test_project_cmake",
|
|
23
|
+
"test_project_cmake_vcpkg",
|
|
22
24
|
],
|
|
23
25
|
)
|
|
24
26
|
def test_basic(self, project):
|
hatch_cpp/tests/test_structs.py
CHANGED
|
@@ -5,7 +5,7 @@ import pytest
|
|
|
5
5
|
from pydantic import ValidationError
|
|
6
6
|
from toml import loads
|
|
7
7
|
|
|
8
|
-
from hatch_cpp
|
|
8
|
+
from hatch_cpp import HatchCppBuildConfig, HatchCppBuildPlan, HatchCppLibrary, HatchCppPlatform
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class TestStructs:
|
hatch_cpp/toolchains/__init__.py
CHANGED
hatch_cpp/toolchains/cmake.py
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from os import environ
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from sys import version_info
|
|
6
|
+
from typing import Any, Dict, Optional, Union
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from .common import Platform
|
|
11
|
+
|
|
12
|
+
__all__ = ("HatchCppCmakeConfiguration",)
|
|
13
|
+
|
|
14
|
+
DefaultMSVCGenerator = {
|
|
15
|
+
"12": "Visual Studio 12 2013",
|
|
16
|
+
"14": "Visual Studio 14 2015",
|
|
17
|
+
"14.0": "Visual Studio 14 2015",
|
|
18
|
+
"14.1": "Visual Studio 15 2017",
|
|
19
|
+
"14.2": "Visual Studio 16 2019",
|
|
20
|
+
"14.3": "Visual Studio 17 2022",
|
|
21
|
+
"14.4": "Visual Studio 17 2022",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class HatchCppCmakeConfiguration(BaseModel):
|
|
26
|
+
root: Optional[Path] = None
|
|
27
|
+
build: Path = Field(default_factory=lambda: Path("build"))
|
|
28
|
+
install: Optional[Path] = Field(default=None)
|
|
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)
|
|
33
|
+
|
|
34
|
+
include_flags: Optional[Dict[str, Union[str, int, float, bool]]] = Field(default=None)
|
|
35
|
+
|
|
36
|
+
def generate(self, config) -> Dict[str, Any]:
|
|
37
|
+
commands = []
|
|
38
|
+
|
|
39
|
+
# Derive prefix
|
|
40
|
+
if self.cmake_arg_prefix is None:
|
|
41
|
+
self.cmake_arg_prefix = f"{config.name.replace('.', '_').replace('-', '_').upper()}_"
|
|
42
|
+
|
|
43
|
+
# Append base command
|
|
44
|
+
commands.append(f"cmake {Path(self.root).parent} -DCMAKE_BUILD_TYPE={config.build_type} -B {self.build}")
|
|
45
|
+
|
|
46
|
+
# Hook in to vcpkg if active
|
|
47
|
+
if "vcpkg" in config._active_toolchains:
|
|
48
|
+
commands[-1] += f" -DCMAKE_TOOLCHAIN_FILE={Path(config.vcpkg.vcpkg_root) / 'scripts' / 'buildsystems' / 'vcpkg.cmake'}"
|
|
49
|
+
|
|
50
|
+
# Setup install path
|
|
51
|
+
if self.install:
|
|
52
|
+
commands[-1] += f" -DCMAKE_INSTALL_PREFIX={self.install}"
|
|
53
|
+
else:
|
|
54
|
+
commands[-1] += f" -DCMAKE_INSTALL_PREFIX={Path(self.root).parent}"
|
|
55
|
+
|
|
56
|
+
# TODO: CMAKE_CXX_COMPILER
|
|
57
|
+
if config.platform.platform == "win32":
|
|
58
|
+
# TODO: prefix?
|
|
59
|
+
commands[-1] += f' -G "{environ.get("CMAKE_GENERATOR", "Visual Studio 17 2022")}"'
|
|
60
|
+
|
|
61
|
+
# Put in CMake flags
|
|
62
|
+
args = self.cmake_args.copy()
|
|
63
|
+
for platform, env_args in self.cmake_env_args.items():
|
|
64
|
+
if platform == config.platform.platform:
|
|
65
|
+
for key, value in env_args.items():
|
|
66
|
+
args[key] = value
|
|
67
|
+
for key, value in args.items():
|
|
68
|
+
commands[-1] += f" -D{self.cmake_arg_prefix}{key.upper()}={value}"
|
|
69
|
+
|
|
70
|
+
# Include customs
|
|
71
|
+
if self.include_flags:
|
|
72
|
+
if self.include_flags.get("python_version", False):
|
|
73
|
+
commands[-1] += f" -D{self.cmake_arg_prefix}PYTHON_VERSION={version_info.major}.{version_info.minor}"
|
|
74
|
+
if self.include_flags.get("manylinux", False) and config.platform.platform == "linux":
|
|
75
|
+
commands[-1] += f" -D{self.cmake_arg_prefix}MANYLINUX=ON"
|
|
76
|
+
|
|
77
|
+
# Include mac deployment target
|
|
78
|
+
if config.platform.platform == "darwin":
|
|
79
|
+
commands[-1] += f" -DCMAKE_OSX_DEPLOYMENT_TARGET={environ.get('OSX_DEPLOYMENT_TARGET', '11')}"
|
|
80
|
+
|
|
81
|
+
# Append build command
|
|
82
|
+
commands.append(f"cmake --build {self.build} --config {config.build_type}")
|
|
83
|
+
|
|
84
|
+
# Append install command
|
|
85
|
+
commands.append(f"cmake --install {self.build} --config {config.build_type}")
|
|
86
|
+
|
|
87
|
+
return commands
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from os import environ
|
|
3
|
+
from os import environ
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from re import match
|
|
6
6
|
from shutil import which
|
|
7
|
-
from sys import executable, platform as sys_platform
|
|
7
|
+
from sys import executable, platform as sys_platform
|
|
8
8
|
from sysconfig import get_path
|
|
9
|
-
from typing import Any,
|
|
9
|
+
from typing import Any, List, Literal, Optional
|
|
10
10
|
|
|
11
11
|
from pydantic import AliasChoices, BaseModel, Field, field_validator, model_validator
|
|
12
12
|
|
|
13
13
|
__all__ = (
|
|
14
|
-
"
|
|
14
|
+
"BuildType",
|
|
15
|
+
"CompilerToolchain",
|
|
16
|
+
"Toolchain",
|
|
17
|
+
"Language",
|
|
18
|
+
"Binding",
|
|
19
|
+
"Platform",
|
|
20
|
+
"PlatformDefaults",
|
|
15
21
|
"HatchCppLibrary",
|
|
16
22
|
"HatchCppPlatform",
|
|
17
|
-
"HatchCppBuildPlan",
|
|
18
23
|
)
|
|
19
24
|
|
|
25
|
+
|
|
20
26
|
BuildType = Literal["debug", "release"]
|
|
21
27
|
CompilerToolchain = Literal["gcc", "clang", "msvc"]
|
|
28
|
+
Toolchain = Literal["vcpkg", "cmake", "vanilla"]
|
|
22
29
|
Language = Literal["c", "c++"]
|
|
23
30
|
Binding = Literal["cpython", "pybind11", "nanobind", "generic"]
|
|
24
31
|
Platform = Literal["linux", "darwin", "win32"]
|
|
@@ -231,118 +238,3 @@ class HatchCppPlatform(BaseModel):
|
|
|
231
238
|
while flags.count(" "):
|
|
232
239
|
flags = flags.replace(" ", " ")
|
|
233
240
|
return flags
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
class HatchCppCmakeConfiguration(BaseModel):
|
|
237
|
-
root: Path
|
|
238
|
-
build: Path = Field(default_factory=lambda: Path("build"))
|
|
239
|
-
install: Optional[Path] = Field(default=None)
|
|
240
|
-
|
|
241
|
-
cmake_arg_prefix: Optional[str] = Field(default=None)
|
|
242
|
-
cmake_args: Dict[str, str] = Field(default_factory=dict)
|
|
243
|
-
cmake_env_args: Dict[Platform, Dict[str, str]] = Field(default_factory=dict)
|
|
244
|
-
|
|
245
|
-
include_flags: Optional[Dict[str, Any]] = Field(default=None)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
class HatchCppBuildConfig(BaseModel):
|
|
249
|
-
"""Build config values for Hatch C++ Builder."""
|
|
250
|
-
|
|
251
|
-
verbose: Optional[bool] = Field(default=False)
|
|
252
|
-
name: Optional[str] = Field(default=None)
|
|
253
|
-
libraries: List[HatchCppLibrary] = Field(default_factory=list)
|
|
254
|
-
cmake: Optional[HatchCppCmakeConfiguration] = Field(default=None)
|
|
255
|
-
platform: Optional[HatchCppPlatform] = Field(default_factory=HatchCppPlatform.default)
|
|
256
|
-
|
|
257
|
-
@model_validator(mode="wrap")
|
|
258
|
-
@classmethod
|
|
259
|
-
def validate_model(cls, data, handler):
|
|
260
|
-
if "toolchain" in data:
|
|
261
|
-
data["platform"] = HatchCppPlatform.platform_for_toolchain(data["toolchain"])
|
|
262
|
-
data.pop("toolchain")
|
|
263
|
-
elif "platform" not in data:
|
|
264
|
-
data["platform"] = HatchCppPlatform.default()
|
|
265
|
-
if "cc" in data:
|
|
266
|
-
data["platform"].cc = data["cc"]
|
|
267
|
-
data.pop("cc")
|
|
268
|
-
if "cxx" in data:
|
|
269
|
-
data["platform"].cxx = data["cxx"]
|
|
270
|
-
data.pop("cxx")
|
|
271
|
-
if "ld" in data:
|
|
272
|
-
data["platform"].ld = data["ld"]
|
|
273
|
-
data.pop("ld")
|
|
274
|
-
model = handler(data)
|
|
275
|
-
if model.cmake and model.libraries:
|
|
276
|
-
raise ValueError("Must not provide libraries when using cmake toolchain.")
|
|
277
|
-
return model
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
class HatchCppBuildPlan(HatchCppBuildConfig):
|
|
281
|
-
build_type: BuildType = "release"
|
|
282
|
-
commands: List[str] = Field(default_factory=list)
|
|
283
|
-
|
|
284
|
-
def generate(self):
|
|
285
|
-
self.commands = []
|
|
286
|
-
if self.libraries:
|
|
287
|
-
for library in self.libraries:
|
|
288
|
-
compile_flags = self.platform.get_compile_flags(library, self.build_type)
|
|
289
|
-
link_flags = self.platform.get_link_flags(library, self.build_type)
|
|
290
|
-
self.commands.append(
|
|
291
|
-
f"{self.platform.cc if library.language == 'c' else self.platform.cxx} {' '.join(library.sources)} {compile_flags} {link_flags}"
|
|
292
|
-
)
|
|
293
|
-
elif self.cmake:
|
|
294
|
-
# Derive prefix
|
|
295
|
-
if self.cmake.cmake_arg_prefix is None:
|
|
296
|
-
self.cmake.cmake_arg_prefix = f"{self.name.replace('.', '_').replace('-', '_').upper()}_"
|
|
297
|
-
|
|
298
|
-
# Append base command
|
|
299
|
-
self.commands.append(f"cmake {Path(self.cmake.root).parent} -DCMAKE_BUILD_TYPE={self.build_type} -B {self.cmake.build}")
|
|
300
|
-
|
|
301
|
-
# Setup install path
|
|
302
|
-
if self.cmake.install:
|
|
303
|
-
self.commands[-1] += f" -DCMAKE_INSTALL_PREFIX={self.cmake.install}"
|
|
304
|
-
else:
|
|
305
|
-
self.commands[-1] += f" -DCMAKE_INSTALL_PREFIX={Path(self.cmake.root).parent}"
|
|
306
|
-
|
|
307
|
-
# TODO: CMAKE_CXX_COMPILER
|
|
308
|
-
if self.platform.platform == "win32":
|
|
309
|
-
# TODO: prefix?
|
|
310
|
-
self.commands[-1] += f' -G "{environ.get("GENERATOR", "Visual Studio 17 2022")}"'
|
|
311
|
-
|
|
312
|
-
# Put in CMake flags
|
|
313
|
-
args = self.cmake.cmake_args.copy()
|
|
314
|
-
for platform, env_args in self.cmake.cmake_env_args.items():
|
|
315
|
-
if platform == self.platform.platform:
|
|
316
|
-
for key, value in env_args.items():
|
|
317
|
-
args[key] = value
|
|
318
|
-
for key, value in args.items():
|
|
319
|
-
self.commands[-1] += f" -D{self.cmake.cmake_arg_prefix}{key.upper()}={value}"
|
|
320
|
-
|
|
321
|
-
# Include customs
|
|
322
|
-
if self.cmake.include_flags:
|
|
323
|
-
if self.cmake.include_flags.get("python_version", False):
|
|
324
|
-
self.commands[-1] += f" -D{self.cmake.cmake_arg_prefix}PYTHON_VERSION={version_info.major}.{version_info.minor}"
|
|
325
|
-
if self.cmake.include_flags.get("manylinux", False) and self.platform.platform == "linux":
|
|
326
|
-
self.commands[-1] += f" -D{self.cmake.cmake_arg_prefix}MANYLINUX=ON"
|
|
327
|
-
|
|
328
|
-
# Include mac deployment target
|
|
329
|
-
if self.platform.platform == "darwin":
|
|
330
|
-
self.commands[-1] += f" -DCMAKE_OSX_DEPLOYMENT_TARGET={environ.get('OSX_DEPLOYMENT_TARGET', '11')}"
|
|
331
|
-
|
|
332
|
-
# Append build command
|
|
333
|
-
self.commands.append(f"cmake --build {self.cmake.build} --config {self.build_type}")
|
|
334
|
-
|
|
335
|
-
# Append install command
|
|
336
|
-
self.commands.append(f"cmake --install {self.cmake.build} --config {self.build_type}")
|
|
337
|
-
|
|
338
|
-
return self.commands
|
|
339
|
-
|
|
340
|
-
def execute(self):
|
|
341
|
-
for command in self.commands:
|
|
342
|
-
system_call(command)
|
|
343
|
-
return self.commands
|
|
344
|
-
|
|
345
|
-
def cleanup(self):
|
|
346
|
-
if self.platform.platform == "win32":
|
|
347
|
-
for temp_obj in Path(".").glob("*.obj"):
|
|
348
|
-
temp_obj.unlink()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from platform import machine as platform_machine
|
|
5
|
+
from sys import platform as sys_platform
|
|
6
|
+
from typing import Literal, Optional
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
__all__ = ("HatchCppVcpkgConfiguration",)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
VcpkgTriplet = Literal[
|
|
14
|
+
"x64-android",
|
|
15
|
+
"x64-osx",
|
|
16
|
+
"x64-linux",
|
|
17
|
+
"x64-uwp",
|
|
18
|
+
"x64-windows",
|
|
19
|
+
"x64-windows-release",
|
|
20
|
+
"x64-windows-static",
|
|
21
|
+
"x64-windows-static-md",
|
|
22
|
+
"x86-windows",
|
|
23
|
+
"arm-neon-android",
|
|
24
|
+
"arm64-android",
|
|
25
|
+
"arm64-osx",
|
|
26
|
+
"arm64-uwp",
|
|
27
|
+
"arm64-windows",
|
|
28
|
+
"arm64-windows-static-md",
|
|
29
|
+
]
|
|
30
|
+
VcpkgPlatformDefaults = {
|
|
31
|
+
("linux", "x86_64"): "x64-linux",
|
|
32
|
+
# ("linux", "arm64"): "",
|
|
33
|
+
("darwin", "x86_64"): "x64-osx",
|
|
34
|
+
("darwin", "arm64"): "arm64-osx",
|
|
35
|
+
("win32", "x86_64"): "x64-windows-static-md",
|
|
36
|
+
("win32", "arm64"): "arm64-windows-static-md",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class HatchCppVcpkgConfiguration(BaseModel):
|
|
41
|
+
vcpkg: Optional[str] = Field(default="vcpkg.json")
|
|
42
|
+
vcpkg_root: Optional[Path] = Field(default=Path("vcpkg"))
|
|
43
|
+
vcpkg_repo: Optional[str] = Field(default="https://github.com/microsoft/vcpkg.git")
|
|
44
|
+
vcpkg_triplet: Optional[VcpkgTriplet] = Field(default=None)
|
|
45
|
+
|
|
46
|
+
# TODO: overlay
|
|
47
|
+
|
|
48
|
+
def generate(self, config):
|
|
49
|
+
commands = []
|
|
50
|
+
|
|
51
|
+
if self.vcpkg_triplet is None:
|
|
52
|
+
self.vcpkg_triplet = VcpkgPlatformDefaults.get((sys_platform, platform_machine()))
|
|
53
|
+
if self.vcpkg_triplet is None:
|
|
54
|
+
raise ValueError(f"Could not determine vcpkg triplet for platform {sys_platform} and architecture {platform_machine()}")
|
|
55
|
+
|
|
56
|
+
if self.vcpkg and Path(self.vcpkg).exists():
|
|
57
|
+
if not Path(self.vcpkg_root).exists():
|
|
58
|
+
commands.append(f"git clone {self.vcpkg_repo} {self.vcpkg_root}")
|
|
59
|
+
commands.append(
|
|
60
|
+
f"./{self.vcpkg_root / 'bootstrap-vcpkg.sh' if sys_platform != 'win32' else self.vcpkg_root / 'sbootstrap-vcpkg.bat'}"
|
|
61
|
+
)
|
|
62
|
+
commands.append(f"./{self.vcpkg_root / 'vcpkg'} install --triplet {self.vcpkg_triplet}")
|
|
63
|
+
|
|
64
|
+
return commands
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hatch-cpp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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.9
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -20,7 +19,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.14
|
|
21
20
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
22
21
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
23
|
-
Requires-Python: >=3.
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: hatch-build<0.5,>=0.4
|
|
24
24
|
Requires-Dist: hatchling>=1.20
|
|
25
25
|
Requires-Dist: pydantic
|
|
26
26
|
Provides-Extra: develop
|
|
@@ -28,15 +28,15 @@ Requires-Dist: build; extra == 'develop'
|
|
|
28
28
|
Requires-Dist: bump-my-version; extra == 'develop'
|
|
29
29
|
Requires-Dist: check-manifest; extra == 'develop'
|
|
30
30
|
Requires-Dist: codespell<2.5,>=2.4; extra == 'develop'
|
|
31
|
-
Requires-Dist: hatch-build; extra == 'develop'
|
|
31
|
+
Requires-Dist: hatch-build>=0.3.2; extra == 'develop'
|
|
32
32
|
Requires-Dist: hatchling; extra == 'develop'
|
|
33
33
|
Requires-Dist: mdformat-tables>=1; extra == 'develop'
|
|
34
|
-
Requires-Dist: mdformat<
|
|
34
|
+
Requires-Dist: mdformat<1.1,>=0.7.22; extra == 'develop'
|
|
35
35
|
Requires-Dist: nanobind<2.10.0; extra == 'develop'
|
|
36
36
|
Requires-Dist: pybind11; extra == 'develop'
|
|
37
37
|
Requires-Dist: pytest; extra == 'develop'
|
|
38
38
|
Requires-Dist: pytest-cov; extra == 'develop'
|
|
39
|
-
Requires-Dist: ruff; extra == 'develop'
|
|
39
|
+
Requires-Dist: ruff<0.15,>=0.9; extra == 'develop'
|
|
40
40
|
Requires-Dist: toml; extra == 'develop'
|
|
41
41
|
Requires-Dist: twine; extra == 'develop'
|
|
42
42
|
Requires-Dist: uv; extra == 'develop'
|
|
@@ -128,6 +128,20 @@ cmake_env_args = {} # env-specific cmake args to pass
|
|
|
128
128
|
include_flags = {} # include flags to pass -D
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
+
### CLI
|
|
132
|
+
|
|
133
|
+
`hatch-cpp` is integrated with [`hatch-build`](https://github.com/python-project-templates/hatch-build) to allow easy configuration of options via command line:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
hatch-build \
|
|
137
|
+
-- \
|
|
138
|
+
--verbose \
|
|
139
|
+
--platform linux \
|
|
140
|
+
--vcpkg.vcpkg a/path/to/vcpkg.json \
|
|
141
|
+
--libraries.0.binding pybind11 \
|
|
142
|
+
--libraries.0.include-dirs cpp,another-dir
|
|
143
|
+
```
|
|
144
|
+
|
|
131
145
|
### Environment Variables
|
|
132
146
|
|
|
133
147
|
`hatch-cpp` will respect standard environment variables for compiler control.
|
|
@@ -1,21 +1,34 @@
|
|
|
1
|
-
hatch_cpp/__init__.py,sha256=
|
|
1
|
+
hatch_cpp/__init__.py,sha256=0H1fLq61dXqP3350HHLIwqt8Nb1zw8zIz5TsIkYHASQ,114
|
|
2
|
+
hatch_cpp/config.py,sha256=8UIdlc6fHEBNgjmLZ1op3x-16BARxx4GJHPwAFQlOUw,3641
|
|
2
3
|
hatch_cpp/hooks.py,sha256=SQkF5WJIgzw-8rvlTzuQvBqdP6K3fHgnh6CZOZFag50,203
|
|
3
|
-
hatch_cpp/plugin.py,sha256=
|
|
4
|
-
hatch_cpp/structs.py,sha256=xNYK3ESJbwsNpBHOWCTtQgAGgjAuswcxUWNcegLI2w8,14898
|
|
4
|
+
hatch_cpp/plugin.py,sha256=pywarl9lNXMMYmYa0OMT2Q3VQGvViusaa0-tZbMA1W4,4523
|
|
5
5
|
hatch_cpp/utils.py,sha256=lxd3U3aMYsTS6DYMc1y17MR16LzgRzv92f_xh87LSg8,297
|
|
6
|
-
hatch_cpp/tests/
|
|
7
|
-
hatch_cpp/tests/
|
|
6
|
+
hatch_cpp/tests/test_hatch_build.py,sha256=q2IKTFi3Pq99UsOyL84V-C9VtFUs3ZcA9UlA8lpRW54,1553
|
|
7
|
+
hatch_cpp/tests/test_projects.py,sha256=vs-kHdiHM7pCqM3oGQsSryq5blRi0HyK5QFfHxlJDi8,1773
|
|
8
|
+
hatch_cpp/tests/test_structs.py,sha256=cpzbPLneEbEONzXmPS1S9PL9mbhya4udc4eqTpU9w6w,2576
|
|
8
9
|
hatch_cpp/tests/test_project_basic/pyproject.toml,sha256=eqM1UVpNmJWDfsuO18ZG_VOV9I4tAWgsM5Dhf49X8Nc,694
|
|
9
10
|
hatch_cpp/tests/test_project_basic/cpp/project/basic.cpp,sha256=gQ2nmdLqIdgaqxSKvkN_vbp6Iv_pAoVIHETXPRnALb0,117
|
|
10
11
|
hatch_cpp/tests/test_project_basic/cpp/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
|
|
11
12
|
hatch_cpp/tests/test_project_basic/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
13
|
hatch_cpp/tests/test_project_cmake/CMakeLists.txt,sha256=J6ijT9x9uSuisNEVIdFVgc_AstU9hbmIUbwvdjn_4GU,2795
|
|
13
14
|
hatch_cpp/tests/test_project_cmake/Makefile,sha256=Vfr65pvnktWTUeuvpMWqIxDR-7V9MT4PQAyj-WHG_pI,4357
|
|
14
|
-
hatch_cpp/tests/test_project_cmake/pyproject.toml,sha256=
|
|
15
|
+
hatch_cpp/tests/test_project_cmake/pyproject.toml,sha256=judDNJ0qYM6-ocGXtUEHQlUzyj8GsF5qoJ-jPDsIAdA,815
|
|
15
16
|
hatch_cpp/tests/test_project_cmake/cpp/project/basic.cpp,sha256=gQ2nmdLqIdgaqxSKvkN_vbp6Iv_pAoVIHETXPRnALb0,117
|
|
16
17
|
hatch_cpp/tests/test_project_cmake/cpp/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
|
|
17
18
|
hatch_cpp/tests/test_project_cmake/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
19
|
hatch_cpp/tests/test_project_cmake/project/include/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
|
|
20
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/CMakeLists.txt,sha256=J6ijT9x9uSuisNEVIdFVgc_AstU9hbmIUbwvdjn_4GU,2795
|
|
21
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/Makefile,sha256=Vfr65pvnktWTUeuvpMWqIxDR-7V9MT4PQAyj-WHG_pI,4357
|
|
22
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/pyproject.toml,sha256=pu9RWhm_FY7KlcdOg2nmp-obnStnPJ04jW-bxei704w,814
|
|
23
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/vcpkg.json,sha256=3D_Mm48_-srxYzbdHNCVO00eFLLGZfsFfL6IMcK0x3E,162
|
|
24
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/cpp/project/basic.cpp,sha256=gQ2nmdLqIdgaqxSKvkN_vbp6Iv_pAoVIHETXPRnALb0,117
|
|
25
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/cpp/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
|
|
26
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
hatch_cpp/tests/test_project_cmake_vcpkg/project/include/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
|
|
28
|
+
hatch_cpp/tests/test_project_hatch_build/pyproject.toml,sha256=CyOB1ZhiqqBQOZJoROVIRew66DVjoN2tIqBlQA-F_V8,812
|
|
29
|
+
hatch_cpp/tests/test_project_hatch_build/cpp/project/basic.cpp,sha256=L4v9AUveWWQX8Z2GMRREsEGLz-A_NCeuX0KiyppDmbc,30
|
|
30
|
+
hatch_cpp/tests/test_project_hatch_build/cpp/project/basic.hpp,sha256=AK2FKdlqBwH5jnRUdJXSbWvRr-gSVsUKSG0PiYNsW7A,155
|
|
31
|
+
hatch_cpp/tests/test_project_hatch_build/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
32
|
hatch_cpp/tests/test_project_limited_api/pyproject.toml,sha256=k_2y7YpZP5I-KPvKOZLmnHqoKXVE2oVM8fjxtRKoTo0,726
|
|
20
33
|
hatch_cpp/tests/test_project_limited_api/cpp/project/basic.cpp,sha256=gQ2nmdLqIdgaqxSKvkN_vbp6Iv_pAoVIHETXPRnALb0,117
|
|
21
34
|
hatch_cpp/tests/test_project_limited_api/cpp/project/basic.hpp,sha256=SO5GhPj8k3RzWrfH37lFSDc8w1Vf3yqTUhxmr1hnoko,422
|
|
@@ -36,10 +49,17 @@ hatch_cpp/tests/test_project_pybind/pyproject.toml,sha256=3IVlSprxx8XaC36s6OSgKr
|
|
|
36
49
|
hatch_cpp/tests/test_project_pybind/cpp/project/basic.cpp,sha256=MT3eCSQKr4guI3XZHV8kw8PoBGC6LEK8ClxnNMBnvnI,78
|
|
37
50
|
hatch_cpp/tests/test_project_pybind/cpp/project/basic.hpp,sha256=LZSfCfhLY_91MBOxtnvDk7DcceO-9GhCHKpMnAjGe18,146
|
|
38
51
|
hatch_cpp/tests/test_project_pybind/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
hatch_cpp/
|
|
40
|
-
hatch_cpp/
|
|
41
|
-
hatch_cpp
|
|
42
|
-
hatch_cpp
|
|
43
|
-
hatch_cpp
|
|
44
|
-
hatch_cpp
|
|
45
|
-
hatch_cpp
|
|
52
|
+
hatch_cpp/tests/test_project_pybind_vcpkg/pyproject.toml,sha256=3IVlSprxx8XaC36s6OSgKr-OiSPn6cH6nX8pbp10suM,716
|
|
53
|
+
hatch_cpp/tests/test_project_pybind_vcpkg/vcpkg.json,sha256=3D_Mm48_-srxYzbdHNCVO00eFLLGZfsFfL6IMcK0x3E,162
|
|
54
|
+
hatch_cpp/tests/test_project_pybind_vcpkg/cpp/project/basic.cpp,sha256=MT3eCSQKr4guI3XZHV8kw8PoBGC6LEK8ClxnNMBnvnI,78
|
|
55
|
+
hatch_cpp/tests/test_project_pybind_vcpkg/cpp/project/basic.hpp,sha256=LZSfCfhLY_91MBOxtnvDk7DcceO-9GhCHKpMnAjGe18,146
|
|
56
|
+
hatch_cpp/tests/test_project_pybind_vcpkg/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
|
+
hatch_cpp/toolchains/__init__.py,sha256=anza4tXKxauobWMOUrxX3sEO0qs7sp6VdLXhLae3vkY,64
|
|
58
|
+
hatch_cpp/toolchains/cmake.py,sha256=VQYYqiOu0ZEF0IBuep35Xad7jryWy04-dHYYf7c0XgY,3331
|
|
59
|
+
hatch_cpp/toolchains/common.py,sha256=nBAGQ9B5a7yNgOgohUCsbnDAJACrdQ8lt5dFyb7IXMs,10076
|
|
60
|
+
hatch_cpp/toolchains/vcpkg.py,sha256=fx9lo5EH3HVqg9Fnh5EO67gNsAXcza9eZz4S-Y8piJ0,2097
|
|
61
|
+
hatch_cpp-0.2.0.dist-info/METADATA,sha256=MVd4nLoYpRqU8nWMxmX1bH5uCjdV2gdOUQX-Gh8UxYw,5906
|
|
62
|
+
hatch_cpp-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
63
|
+
hatch_cpp-0.2.0.dist-info/entry_points.txt,sha256=RgXfjpD4iwomJQK5n7FnPkXzb5fOnF5v3DI5hbkgVcw,30
|
|
64
|
+
hatch_cpp-0.2.0.dist-info/licenses/LICENSE,sha256=FWyFTpd5xXEz50QpGDtsyIv6dgR2z_dHdoab_Nq_KMw,11452
|
|
65
|
+
hatch_cpp-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|