hatch-cpp 0.0.0__tar.gz → 0.1.1__tar.gz
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-0.1.1/.gitignore +169 -0
- {hatch_cpp-0.0.0 → hatch_cpp-0.1.1}/LICENSE +1 -1
- hatch_cpp-0.1.1/PKG-INFO +46 -0
- hatch_cpp-0.1.1/README.md +13 -0
- hatch_cpp-0.1.1/hatch_cpp/__init__.py +1 -0
- hatch_cpp-0.1.1/hatch_cpp/__main__.py +4 -0
- hatch_cpp-0.1.1/hatch_cpp/hooks.py +10 -0
- hatch_cpp-0.1.1/hatch_cpp/plugin.py +89 -0
- hatch_cpp-0.1.1/hatch_cpp/structs.py +159 -0
- hatch_cpp-0.1.1/hatch_cpp/tests/test_all.py +2 -0
- hatch_cpp-0.1.1/hatch_cpp/tests/test_project_basic/basic_project/__init__.py +0 -0
- hatch_cpp-0.1.1/hatch_cpp/tests/test_project_basic/cpp/basic-project/basic.cpp +5 -0
- hatch_cpp-0.1.1/hatch_cpp/tests/test_project_basic/cpp/basic-project/basic.hpp +17 -0
- hatch_cpp-0.1.1/hatch_cpp/tests/test_project_basic/pyproject.toml +63 -0
- hatch_cpp-0.1.1/hatch_cpp/tests/test_project_basic.py +28 -0
- hatch_cpp-0.1.1/hatch_cpp/toolchains/__init__.py +0 -0
- hatch_cpp-0.1.1/hatch_cpp/toolchains/cmake.py +0 -0
- hatch_cpp-0.1.1/hatch_cpp/utils.py +120 -0
- hatch_cpp-0.1.1/pyproject.toml +128 -0
- hatch_cpp-0.0.0/PKG-INFO +0 -224
- hatch_cpp-0.0.0/README.md +0 -1
- hatch_cpp-0.0.0/hatch_cpp.egg-info/PKG-INFO +0 -224
- hatch_cpp-0.0.0/hatch_cpp.egg-info/SOURCES.txt +0 -8
- hatch_cpp-0.0.0/hatch_cpp.egg-info/dependency_links.txt +0 -1
- hatch_cpp-0.0.0/hatch_cpp.egg-info/top_level.txt +0 -1
- hatch_cpp-0.0.0/pyproject.toml +0 -29
- hatch_cpp-0.0.0/setup.cfg +0 -4
- hatch_cpp-0.0.0/setup.py +0 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.a
|
|
8
|
+
*.so
|
|
9
|
+
*.obj
|
|
10
|
+
*.dll
|
|
11
|
+
*.exp
|
|
12
|
+
*.lib
|
|
13
|
+
|
|
14
|
+
# Distribution / packaging
|
|
15
|
+
.Python
|
|
16
|
+
env/
|
|
17
|
+
build/
|
|
18
|
+
develop-eggs/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
var/
|
|
28
|
+
*.egg-info/
|
|
29
|
+
.installed.cfg
|
|
30
|
+
*.egg
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
python_junit.xml
|
|
49
|
+
junit.xml
|
|
50
|
+
nosetests.xml
|
|
51
|
+
coverage.xml
|
|
52
|
+
*,cover
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache
|
|
55
|
+
.ruff_cache
|
|
56
|
+
js/playwright-report
|
|
57
|
+
|
|
58
|
+
# Translations
|
|
59
|
+
*.mo
|
|
60
|
+
*.pot
|
|
61
|
+
|
|
62
|
+
# Django stuff:
|
|
63
|
+
*.log
|
|
64
|
+
local_settings.py
|
|
65
|
+
|
|
66
|
+
# Flask instance folder
|
|
67
|
+
instance/
|
|
68
|
+
|
|
69
|
+
# Scrapy stuff:
|
|
70
|
+
.scrapy
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
docs/source
|
|
75
|
+
|
|
76
|
+
# PyBuilder
|
|
77
|
+
target/
|
|
78
|
+
|
|
79
|
+
# IPython Notebook
|
|
80
|
+
.ipynb_checkpoints
|
|
81
|
+
*.ipynb
|
|
82
|
+
.autoversion
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# celery beat schedule file
|
|
88
|
+
celerybeat-schedule
|
|
89
|
+
|
|
90
|
+
# dotenv
|
|
91
|
+
.env
|
|
92
|
+
|
|
93
|
+
# virtualenv
|
|
94
|
+
venv/
|
|
95
|
+
ENV/
|
|
96
|
+
|
|
97
|
+
# Spyder project settings
|
|
98
|
+
.spyderproject
|
|
99
|
+
|
|
100
|
+
# Rope project settings
|
|
101
|
+
.ropeproject
|
|
102
|
+
|
|
103
|
+
# =========================
|
|
104
|
+
# Operating System Files
|
|
105
|
+
# =========================
|
|
106
|
+
|
|
107
|
+
# OSX
|
|
108
|
+
# =========================
|
|
109
|
+
|
|
110
|
+
.DS_Store
|
|
111
|
+
.AppleDouble
|
|
112
|
+
.LSOverride
|
|
113
|
+
|
|
114
|
+
# Thumbnails
|
|
115
|
+
._*
|
|
116
|
+
|
|
117
|
+
# Files that might appear in the root of a volume
|
|
118
|
+
.DocumentRevisions-V100
|
|
119
|
+
.fseventsd
|
|
120
|
+
.Spotlight-V100
|
|
121
|
+
.TemporaryItems
|
|
122
|
+
.Trashes
|
|
123
|
+
.VolumeIcon.icns
|
|
124
|
+
|
|
125
|
+
# Directories potentially created on remote AFP share
|
|
126
|
+
.AppleDB
|
|
127
|
+
.AppleDesktop
|
|
128
|
+
Network Trash Folder
|
|
129
|
+
Temporary Items
|
|
130
|
+
.apdisk
|
|
131
|
+
|
|
132
|
+
# Windows
|
|
133
|
+
# =========================
|
|
134
|
+
|
|
135
|
+
# Windows image file caches
|
|
136
|
+
Thumbs.db
|
|
137
|
+
ehthumbs.db
|
|
138
|
+
|
|
139
|
+
# Folder config file
|
|
140
|
+
Desktop.ini
|
|
141
|
+
|
|
142
|
+
# Recycle Bin used on file shares
|
|
143
|
+
$RECYCLE.BIN/
|
|
144
|
+
|
|
145
|
+
# Windows Installer files
|
|
146
|
+
*.cab
|
|
147
|
+
*.msi
|
|
148
|
+
*.msm
|
|
149
|
+
*.msp
|
|
150
|
+
|
|
151
|
+
# Windows shortcuts
|
|
152
|
+
*.lnk
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# NPM
|
|
156
|
+
# ----
|
|
157
|
+
**/node_modules/
|
|
158
|
+
|
|
159
|
+
# Coverage data
|
|
160
|
+
# -------------
|
|
161
|
+
**/coverage/
|
|
162
|
+
|
|
163
|
+
# Notebook and lab extensions
|
|
164
|
+
|
|
165
|
+
nbprint/extension/*
|
|
166
|
+
nbprint/templates/nbprint/static/*
|
|
167
|
+
nbprint/voila/static/*
|
|
168
|
+
tmp.html
|
|
169
|
+
examples/output/
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
hatch_cpp-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hatch-cpp
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Hatch plugin for C++ builds
|
|
5
|
+
Project-URL: Repository, https://github.com/python-project-templates/hatch-cpp
|
|
6
|
+
Project-URL: Homepage, https://github.com/python-project-templates/hatch-cpp
|
|
7
|
+
Author-email: the hatch-cpp authors <t.paine154@gmail.com>
|
|
8
|
+
License: Apache-2.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: build,c++,cmake,cpp,hatch,python
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
20
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Requires-Dist: hatchling>=1.20
|
|
23
|
+
Provides-Extra: develop
|
|
24
|
+
Requires-Dist: build; extra == 'develop'
|
|
25
|
+
Requires-Dist: bump-my-version; extra == 'develop'
|
|
26
|
+
Requires-Dist: check-manifest; extra == 'develop'
|
|
27
|
+
Requires-Dist: pytest; extra == 'develop'
|
|
28
|
+
Requires-Dist: pytest-cov; extra == 'develop'
|
|
29
|
+
Requires-Dist: ruff<0.9,>=0.3; extra == 'develop'
|
|
30
|
+
Requires-Dist: twine; extra == 'develop'
|
|
31
|
+
Requires-Dist: wheel; extra == 'develop'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# hatch-cpp
|
|
35
|
+
|
|
36
|
+
Hatch plugin for C++ builds
|
|
37
|
+
|
|
38
|
+
[](https://github.com/python-project-templates/hatch-cpp/actions/workflows/build.yml)
|
|
39
|
+
[](https://codecov.io/gh/python-project-templates/hatch-cpp)
|
|
40
|
+
[](https://github.com/python-project-templates/hatch-cpp)
|
|
41
|
+
[](https://pypi.python.org/pypi/hatch-cpp)
|
|
42
|
+
|
|
43
|
+
## Overview
|
|
44
|
+
|
|
45
|
+
> [!NOTE]
|
|
46
|
+
> This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# hatch-cpp
|
|
2
|
+
|
|
3
|
+
Hatch plugin for C++ builds
|
|
4
|
+
|
|
5
|
+
[](https://github.com/python-project-templates/hatch-cpp/actions/workflows/build.yml)
|
|
6
|
+
[](https://codecov.io/gh/python-project-templates/hatch-cpp)
|
|
7
|
+
[](https://github.com/python-project-templates/hatch-cpp)
|
|
8
|
+
[](https://pypi.python.org/pypi/hatch-cpp)
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
> [!NOTE]
|
|
13
|
+
> This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.1"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import typing as t
|
|
6
|
+
from dataclasses import fields
|
|
7
|
+
|
|
8
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
9
|
+
|
|
10
|
+
from .structs import HatchCppBuildConfig, HatchCppBuildPlan, HatchCppLibrary, HatchCppPlatform
|
|
11
|
+
|
|
12
|
+
__all__ = ("HatchCppBuildHook",)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class HatchCppBuildHook(BuildHookInterface[HatchCppBuildConfig]):
|
|
16
|
+
"""The hatch-cpp build hook."""
|
|
17
|
+
|
|
18
|
+
PLUGIN_NAME = "hatch-cpp"
|
|
19
|
+
_logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
def initialize(self, version: str, _: dict[str, t.Any]) -> None:
|
|
22
|
+
"""Initialize the plugin."""
|
|
23
|
+
self._logger.info("Running hatch-cpp")
|
|
24
|
+
|
|
25
|
+
if self.target_name != "wheel":
|
|
26
|
+
self._logger.info("ignoring target name %s", self.target_name)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
if os.getenv("SKIP_HATCH_CPP"):
|
|
30
|
+
self._logger.info("Skipping the build hook since SKIP_HATCH_CPP was set")
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
kwargs = {k.replace("-", "_"): v if not isinstance(v, bool) else str(v) for k, v in self.config.items()}
|
|
34
|
+
available_fields = [f.name for f in fields(HatchCppBuildConfig)]
|
|
35
|
+
for key in list(kwargs):
|
|
36
|
+
if key not in available_fields:
|
|
37
|
+
del kwargs[key]
|
|
38
|
+
config = HatchCppBuildConfig(**kwargs)
|
|
39
|
+
|
|
40
|
+
library_kwargs = [
|
|
41
|
+
{k.replace("-", "_"): v if not isinstance(v, bool) else str(v) for k, v in library_kwargs.items()} for library_kwargs in config.libraries
|
|
42
|
+
]
|
|
43
|
+
libraries = [HatchCppLibrary(**library_kwargs) for library_kwargs in library_kwargs]
|
|
44
|
+
platform = HatchCppPlatform.default()
|
|
45
|
+
if config.toolchain == "raw":
|
|
46
|
+
build_plan = HatchCppBuildPlan(libraries=libraries, platform=platform)
|
|
47
|
+
build_plan.generate()
|
|
48
|
+
if config.verbose:
|
|
49
|
+
for command in build_plan.commands:
|
|
50
|
+
self._logger.info(command)
|
|
51
|
+
build_plan.execute()
|
|
52
|
+
build_plan.cleanup()
|
|
53
|
+
|
|
54
|
+
# build_kwargs = config.build_kwargs
|
|
55
|
+
# if version == "editable":
|
|
56
|
+
# build_kwargs = config.editable_build_kwargs or build_kwargs
|
|
57
|
+
|
|
58
|
+
# should_skip_build = False
|
|
59
|
+
# if not config.build_function:
|
|
60
|
+
# log.warning("No build function found")
|
|
61
|
+
# should_skip_build = True
|
|
62
|
+
|
|
63
|
+
# elif config.skip_if_exists and version == "standard":
|
|
64
|
+
# should_skip_build = should_skip(config.skip_if_exists)
|
|
65
|
+
# if should_skip_build:
|
|
66
|
+
# log.info("Skip-if-exists file(s) found")
|
|
67
|
+
|
|
68
|
+
# # Get build function and call it with normalized parameter names.
|
|
69
|
+
# if not should_skip_build and config.build_function:
|
|
70
|
+
# build_func = get_build_func(config.build_function)
|
|
71
|
+
# build_kwargs = normalize_kwargs(build_kwargs)
|
|
72
|
+
# log.info("Building with %s", config.build_function)
|
|
73
|
+
# log.info("With kwargs: %s", build_kwargs)
|
|
74
|
+
# try:
|
|
75
|
+
# build_func(self.target_name, version, **build_kwargs)
|
|
76
|
+
# except Exception as e:
|
|
77
|
+
# if version == "editable" and config.optional_editable_build.lower() == "true":
|
|
78
|
+
# warnings.warn(f"Encountered build error:\n{e}", stacklevel=2)
|
|
79
|
+
# else:
|
|
80
|
+
# raise e
|
|
81
|
+
# else:
|
|
82
|
+
# log.info("Skipping build")
|
|
83
|
+
|
|
84
|
+
# # Ensure targets in distributable dists.
|
|
85
|
+
# if version == "standard":
|
|
86
|
+
# ensure_targets(config.ensured_targets)
|
|
87
|
+
|
|
88
|
+
self._logger.info("Finished running hatch-cpp")
|
|
89
|
+
return
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from os import environ, system
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from sys import executable, platform as sys_platform
|
|
7
|
+
from sysconfig import get_path
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from hatchling.builders.config import BuilderConfig
|
|
11
|
+
|
|
12
|
+
__all__ = (
|
|
13
|
+
"HatchCppBuildConfig",
|
|
14
|
+
"HatchCppLibrary",
|
|
15
|
+
"HatchCppPlatform",
|
|
16
|
+
"HatchCppBuildPlan",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
Platform = Literal["linux", "darwin", "win32"]
|
|
20
|
+
CompilerToolchain = Literal["gcc", "clang", "msvc"]
|
|
21
|
+
PlatformDefaults = {
|
|
22
|
+
"linux": {"CC": "gcc", "CXX": "g++"},
|
|
23
|
+
"darwin": {"CC": "clang", "CXX": "clang++"},
|
|
24
|
+
"win32": {"CC": "cl", "CXX": "cl"},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class HatchCppBuildConfig(BuilderConfig):
|
|
30
|
+
"""Build config values for Hatch C++ Builder."""
|
|
31
|
+
|
|
32
|
+
toolchain: str | None = field(default="raw")
|
|
33
|
+
libraries: list[dict[str, str]] = field(default_factory=list)
|
|
34
|
+
verbose: bool | None = field(default=False)
|
|
35
|
+
# build_function: str | None = None
|
|
36
|
+
# build_kwargs: t.Mapping[str, str] = field(default_factory=dict)
|
|
37
|
+
# editable_build_kwargs: t.Mapping[str, str] = field(default_factory=dict)
|
|
38
|
+
# ensured_targets: list[str] = field(default_factory=list)
|
|
39
|
+
# skip_if_exists: list[str] = field(default_factory=list)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class HatchCppLibrary(object):
|
|
44
|
+
"""A C++ library."""
|
|
45
|
+
|
|
46
|
+
name: str
|
|
47
|
+
sources: list[str]
|
|
48
|
+
|
|
49
|
+
include_dirs: list[str] = field(default_factory=list)
|
|
50
|
+
library_dirs: list[str] = field(default_factory=list)
|
|
51
|
+
libraries: list[str] = field(default_factory=list)
|
|
52
|
+
extra_compile_args: list[str] = field(default_factory=list)
|
|
53
|
+
extra_link_args: list[str] = field(default_factory=list)
|
|
54
|
+
extra_objects: list[str] = field(default_factory=list)
|
|
55
|
+
define_macros: list[str] = field(default_factory=list)
|
|
56
|
+
undef_macros: list[str] = field(default_factory=list)
|
|
57
|
+
|
|
58
|
+
export_symbols: list[str] = field(default_factory=list)
|
|
59
|
+
depends: list[str] = field(default_factory=list)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class HatchCppPlatform(object):
|
|
64
|
+
cc: str
|
|
65
|
+
cxx: str
|
|
66
|
+
platform: Platform
|
|
67
|
+
toolchain: CompilerToolchain
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def default() -> HatchCppPlatform:
|
|
71
|
+
platform = environ.get("HATCH_CPP_PLATFORM", sys_platform)
|
|
72
|
+
CC = environ.get("CC", PlatformDefaults[platform]["CC"])
|
|
73
|
+
CXX = environ.get("CXX", PlatformDefaults[platform]["CXX"])
|
|
74
|
+
if "gcc" in CC and "g++" in CXX:
|
|
75
|
+
toolchain = "gcc"
|
|
76
|
+
elif "clang" in CC and "clang++" in CXX:
|
|
77
|
+
toolchain = "clang"
|
|
78
|
+
elif "cl" in CC and "cl" in CXX:
|
|
79
|
+
toolchain = "msvc"
|
|
80
|
+
else:
|
|
81
|
+
raise Exception(f"Unrecognized toolchain: {CC}, {CXX}")
|
|
82
|
+
return HatchCppPlatform(cc=CC, cxx=CXX, platform=platform, toolchain=toolchain)
|
|
83
|
+
|
|
84
|
+
def get_compile_flags(self, library: HatchCppLibrary) -> str:
|
|
85
|
+
flags = ""
|
|
86
|
+
if self.toolchain == "gcc":
|
|
87
|
+
flags = f"-I{get_path('include')}"
|
|
88
|
+
flags += " " + " ".join(f"-I{d}" for d in library.include_dirs)
|
|
89
|
+
flags += " -fPIC -shared"
|
|
90
|
+
flags += " " + " ".join(library.extra_compile_args)
|
|
91
|
+
flags += " " + " ".join(library.extra_link_args)
|
|
92
|
+
flags += " " + " ".join(library.extra_objects)
|
|
93
|
+
flags += " " + " ".join(f"-l{lib}" for lib in library.libraries)
|
|
94
|
+
flags += " " + " ".join(f"-L{lib}" for lib in library.library_dirs)
|
|
95
|
+
flags += " " + " ".join(f"-D{macro}" for macro in library.define_macros)
|
|
96
|
+
flags += " " + " ".join(f"-U{macro}" for macro in library.undef_macros)
|
|
97
|
+
flags += f" -o {library.name}.so"
|
|
98
|
+
elif self.toolchain == "clang":
|
|
99
|
+
flags = f"-I{get_path('include')} "
|
|
100
|
+
flags += " ".join(f"-I{d}" for d in library.include_dirs)
|
|
101
|
+
flags += " -undefined dynamic_lookup -fPIC -shared"
|
|
102
|
+
flags += " " + " ".join(library.extra_compile_args)
|
|
103
|
+
flags += " " + " ".join(library.extra_link_args)
|
|
104
|
+
flags += " " + " ".join(library.extra_objects)
|
|
105
|
+
flags += " " + " ".join(f"-l{lib}" for lib in library.libraries)
|
|
106
|
+
flags += " " + " ".join(f"-L{lib}" for lib in library.library_dirs)
|
|
107
|
+
flags += " " + " ".join(f"-D{macro}" for macro in library.define_macros)
|
|
108
|
+
flags += " " + " ".join(f"-U{macro}" for macro in library.undef_macros)
|
|
109
|
+
flags += f" -o {library.name}.so"
|
|
110
|
+
elif self.toolchain == "msvc":
|
|
111
|
+
flags = f"/I{get_path('include')} "
|
|
112
|
+
flags += " ".join(f"/I{d}" for d in library.include_dirs)
|
|
113
|
+
flags += " " + " ".join(library.extra_compile_args)
|
|
114
|
+
flags += " " + " ".join(library.extra_link_args)
|
|
115
|
+
flags += " " + " ".join(library.extra_objects)
|
|
116
|
+
flags += " " + " ".join(f"/D{macro}" for macro in library.define_macros)
|
|
117
|
+
flags += " " + " ".join(f"/U{macro}" for macro in library.undef_macros)
|
|
118
|
+
flags += " /EHsc /DWIN32 /LD"
|
|
119
|
+
flags += f" /Fo:{library.name}.obj"
|
|
120
|
+
flags += f" /Fe:{library.name}.pyd"
|
|
121
|
+
flags += " /link /DLL"
|
|
122
|
+
if (Path(executable).parent / "libs").exists():
|
|
123
|
+
flags += f" /LIBPATH:{str(Path(executable).parent / 'libs')}"
|
|
124
|
+
flags += " " + " ".join(f"{lib}.lib" for lib in library.libraries)
|
|
125
|
+
flags += " " + " ".join(f"/LIBPATH:{lib}" for lib in library.library_dirs)
|
|
126
|
+
# clean
|
|
127
|
+
while flags.count(" "):
|
|
128
|
+
flags = flags.replace(" ", " ")
|
|
129
|
+
return flags
|
|
130
|
+
|
|
131
|
+
def get_link_flags(self, library: HatchCppLibrary) -> str:
|
|
132
|
+
flags = ""
|
|
133
|
+
return flags
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@dataclass
|
|
137
|
+
class HatchCppBuildPlan(object):
|
|
138
|
+
libraries: list[HatchCppLibrary] = field(default_factory=list)
|
|
139
|
+
platform: HatchCppPlatform = field(default_factory=HatchCppPlatform.default)
|
|
140
|
+
commands: list[str] = field(default_factory=list)
|
|
141
|
+
|
|
142
|
+
def generate(self):
|
|
143
|
+
self.commands = []
|
|
144
|
+
for library in self.libraries:
|
|
145
|
+
flags = self.platform.get_compile_flags(library)
|
|
146
|
+
self.commands.append(f"{self.platform.cc} {' '.join(library.sources)} {flags}")
|
|
147
|
+
return self.commands
|
|
148
|
+
|
|
149
|
+
def execute(self):
|
|
150
|
+
for command in self.commands:
|
|
151
|
+
system(command)
|
|
152
|
+
return self.commands
|
|
153
|
+
|
|
154
|
+
def cleanup(self):
|
|
155
|
+
if self.platform.platform == "win32":
|
|
156
|
+
for library in self.libraries:
|
|
157
|
+
temp_obj = Path(f"{library.name}.obj")
|
|
158
|
+
if temp_obj.exists():
|
|
159
|
+
temp_obj.unlink()
|
|
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,63 @@
|
|
|
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
|
+
"basic_project/*.dll",
|
|
18
|
+
"basic_project/*.dylib",
|
|
19
|
+
"basic_project/*.so",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[tool.hatch.build.sources]
|
|
23
|
+
src = "/"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.sdist]
|
|
26
|
+
packages = ["basic_project"]
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["basic_project"]
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.hooks.hatch-cpp]
|
|
32
|
+
verbose = true
|
|
33
|
+
libraries = [
|
|
34
|
+
{name = "basic_project/extension", sources = ["cpp/basic-project/basic.cpp"], include-dirs = ["cpp"]}
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
# build-function = "hatch_cpp.cpp_builder"
|
|
38
|
+
|
|
39
|
+
# [tool.hatch.build.hooks.defaults]
|
|
40
|
+
# build-type = "release"
|
|
41
|
+
|
|
42
|
+
# [tool.hatch.build.hooks.env-vars]
|
|
43
|
+
# TODO: these will all be available via
|
|
44
|
+
# CLI after https://github.com/pypa/hatch/pull/1743
|
|
45
|
+
# e.g. --hatch-cpp-build-type=debug
|
|
46
|
+
# build-type = "BUILD_TYPE"
|
|
47
|
+
# ccache = "USE_CCACHE"
|
|
48
|
+
# manylinux = "MANYLINUX"
|
|
49
|
+
# vcpkg = "USE_VCPKG"
|
|
50
|
+
|
|
51
|
+
# [tool.hatch.build.hooks.cmake]
|
|
52
|
+
|
|
53
|
+
# [tool.hatch.build.hooks.vcpkg]
|
|
54
|
+
# triplets = {linux="x64-linux", macos="x64-osx", windows="x64-windows-static-md"}
|
|
55
|
+
# clone = true
|
|
56
|
+
# update = true
|
|
57
|
+
|
|
58
|
+
# [tool.hatch.build.hooks.hatch-cpp.build-kwargs]
|
|
59
|
+
# path = "cpp"
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
asyncio_mode = "strict"
|
|
63
|
+
testpaths = "basic_project/tests"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from os import listdir
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from shutil import rmtree
|
|
4
|
+
from subprocess import check_output
|
|
5
|
+
from sys import path, platform
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestProject:
|
|
9
|
+
def test_basic(self):
|
|
10
|
+
rmtree("hatch_cpp/tests/test_project_basic/basic_project/extension.so", ignore_errors=True)
|
|
11
|
+
rmtree("hatch_cpp/tests/test_project_basic/basic_project/extension.pyd", ignore_errors=True)
|
|
12
|
+
check_output(
|
|
13
|
+
[
|
|
14
|
+
"hatchling",
|
|
15
|
+
"build",
|
|
16
|
+
"--hooks-only",
|
|
17
|
+
],
|
|
18
|
+
cwd="hatch_cpp/tests/test_project_basic",
|
|
19
|
+
)
|
|
20
|
+
if platform == "win32":
|
|
21
|
+
assert "extension.pyd" in listdir("hatch_cpp/tests/test_project_basic/basic_project")
|
|
22
|
+
else:
|
|
23
|
+
assert "extension.so" in listdir("hatch_cpp/tests/test_project_basic/basic_project")
|
|
24
|
+
here = Path(__file__).parent / "test_project_basic"
|
|
25
|
+
path.insert(0, str(here))
|
|
26
|
+
import basic_project.extension
|
|
27
|
+
|
|
28
|
+
assert basic_project.extension.hello() == "A string"
|
|
File without changes
|
|
File without changes
|