Skip to content

Commit ff551c3

Browse files
Update build tools (#462)
1 parent a3b0646 commit ff551c3

14 files changed

Lines changed: 95 additions & 66 deletions

File tree

.github/workflows/python-build.yml

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
cfg:
13-
- { os: windows-2025, python-version: '3.14', architecture: x64 }
14-
- { os: windows-11-arm, python-version: '3.14', architecture: arm64 }
15-
- { os: macos-15, python-version: '3.14', architecture: arm64 }
13+
- { os: windows-2025-vs2026, python-version: '3.14', architecture: x64, whl: 'cp314-win_amd64' }
14+
- { os: windows-11-vs2026-arm, python-version: '3.14', architecture: arm64, whl: 'cp314-win_arm64' }
15+
- { os: macos-15-intel, python-version: '3.14', architecture: x64, whl: 'cp314-macosx_x86_64' }
16+
- { os: macos-15, python-version: '3.14', architecture: arm64, whl: 'cp314-macosx_arm64' }
17+
- { os: ubuntu-24.04, python-version: '3.14', architecture: x64, whl: 'cp314-manylinux_x86_64' }
1618

1719
runs-on: ${{ matrix.cfg.os }}
1820
defaults:
@@ -21,24 +23,30 @@ jobs:
2123

2224
steps:
2325
- name: Clone
24-
uses: actions/checkout@v6
25-
26-
- name: Setup cmake
27-
uses: jwlawson/actions-setup-cmake@v2
26+
uses: actions/checkout@v7
2827

2928
- name: Set up Python
3029
uses: actions/setup-python@v6
3130
with:
3231
python-version: ${{ matrix.cfg.python-version }}
32+
architecture: ${{ matrix.cfg.architecture }}
3333

34-
- name: Install dependencies
35-
shell: bash
34+
- name: Build sdist
3635
run: |
37-
pip install build twine
36+
pip install build
37+
python -m build --sdist --outdir dist .
3838
3939
- name: Build
40+
env:
41+
CIBW_TEST_COMMAND: ""
42+
run: |
43+
pip install cibuildwheel~=4.1
44+
cibuildwheel --only ${{ matrix.cfg.whl }} --output-dir dist .
45+
46+
- name: Install twine
47+
shell: bash
4048
run: |
41-
python -m build .
49+
pip install twine
4250
4351
- name: Publish
4452
env:

.github/workflows/python-stylecheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
steps:
2020
- name: Clone
21-
uses: actions/checkout@v6
21+
uses: actions/checkout@v7
2222

2323
- name: Set up Python
2424
uses: actions/setup-python@v6

.github/workflows/python-unittests.yml

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
cfg:
18-
- { os: windows-2025, python-version: '3.14', architecture: x64 }
19-
- { os: windows-11-arm, python-version: '3.14', architecture: arm64 }
20-
- { os: macos-15-intel, python-version: '3.14', architecture: x64 }
21-
- { os: macos-15, python-version: '3.14', architecture: arm64 }
22-
- { os: ubuntu-24.04, python-version: '3.14', architecture: x64 }
18+
- { os: windows-2025-vs2026, python-version: '3.14', architecture: x64, whl: 'cp314-win_amd64' }
19+
- { os: windows-11-vs2026-arm, python-version: '3.14', architecture: arm64, whl: 'cp314-win_arm64' }
20+
- { os: macos-15-intel, python-version: '3.14', architecture: x64, whl: 'cp314-macosx_x86_64' }
21+
- { os: macos-15, python-version: '3.14', architecture: arm64, whl: 'cp314-macosx_arm64' }
22+
- { os: ubuntu-24.04, python-version: '3.14', architecture: x64, whl: 'cp314-manylinux_x86_64' }
2323

2424
runs-on: ${{ matrix.cfg.os }}
2525
timeout-minutes: 45
@@ -29,21 +29,20 @@ jobs:
2929

3030
steps:
3131
- name: Clone
32-
uses: actions/checkout@v6
33-
34-
- name: Setup cmake
35-
uses: jwlawson/actions-setup-cmake@v2
32+
uses: actions/checkout@v7
3633

3734
- name: Set up Python
3835
uses: actions/setup-python@v6
3936
with:
4037
python-version: ${{ matrix.cfg.python-version }}
4138
architecture: ${{ matrix.cfg.architecture }}
42-
43-
- name: Build
39+
40+
- name: Build and Test
4441
run: |
45-
pip install -v .[dev]
46-
python tools/compile_tests.py
47-
48-
- name: Test with unittest
49-
run: python -m unittest discover -v -s tests
42+
pip install cibuildwheel~=4.1
43+
cibuildwheel --only ${{ matrix.cfg.whl }} --output-dir dist .
44+
45+
- name: Upload artifacts
46+
uses: actions/upload-artifact@v7
47+
with:
48+
path: dist/*

CMakeLists.txt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ if (MSVC)
2626
add_definitions("/MP")
2727
endif()
2828

29-
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
29+
find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED)
3030

3131
# Find libraries
3232
if (NOT TARGET pybind11::module)
@@ -47,10 +47,10 @@ endif()
4747

4848
# Find C++ files
4949
file(REAL_PATH src SOURCE_PATH)
50-
file(GLOB_RECURSE EXTENSION_SOURCES LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.py.cpp)
51-
file(GLOB_RECURSE EXTENSION_HEADERS LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.py.hpp)
52-
file(GLOB_RECURSE SOURCES LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.cpp)
53-
file(GLOB_RECURSE HEADERS LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.hpp)
50+
file(GLOB_RECURSE EXTENSION_SOURCES LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/core/*.py.cpp)
51+
file(GLOB_RECURSE EXTENSION_HEADERS LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/core/*.py.hpp)
52+
file(GLOB_RECURSE SOURCES LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/core/*.cpp)
53+
file(GLOB_RECURSE HEADERS LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/core/*.hpp)
5454
list(REMOVE_ITEM SOURCES ${EXTENSION_SOURCES})
5555
list(REMOVE_ITEM HEADERS ${EXTENSION_HEADERS})
5656

@@ -75,6 +75,11 @@ endforeach()
7575

7676
# Add python extension
7777
pybind11_add_module(_amulet_core)
78+
if(APPLE)
79+
set_target_properties(_amulet_core PROPERTIES INSTALL_RPATH "@loader_path")
80+
elseif(UNIX)
81+
set_target_properties(_amulet_core PROPERTIES INSTALL_RPATH "$ORIGIN")
82+
endif()
7883
set_target_properties(_amulet_core PROPERTIES CXX_VISIBILITY_PRESET hidden)
7984
set_target_properties(_amulet_core PROPERTIES FOLDER "Python")
8085
target_link_libraries(_amulet_core PRIVATE amulet_pybind11_extensions)

get_compiler/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
from tempfile import TemporaryDirectory
44

55

6-
def main() -> str:
6+
def main(sdist: bool = False) -> str:
7+
if sdist:
8+
return "~=4.0"
9+
710
if subprocess.run(["cmake", "--version"]).returncode:
811
raise RuntimeError("Could not find cmake")
912

mypy.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ warn_return_any = True
55
python_version = 3.14
66
explicit_package_bases = True
77
mypy_path = $MYPY_CONFIG_FILE_DIR/src,$MYPY_CONFIG_FILE_DIR/tests
8-
files =
8+
files =
99
src,
1010
tests,
1111
tools,

pyproject.toml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,30 @@ versionfile_source = "src/amulet/core/_version.py"
7373
versionfile_build = "amulet/core/_version.py"
7474
tag_prefix = ""
7575
parentdir_prefix = "amulet_core-"
76+
77+
[tool.cibuildwheel]
78+
test-sources = ["tests", "tools/compile_tests.py"]
79+
test-command = [
80+
"python -m venv venv_build",
81+
"venv_build/bin/pip install {wheel}[dev]",
82+
"venv_build/bin/python tools/compile_tests.py",
83+
"python -m unittest discover -s tests"
84+
]
85+
86+
manylinux-x86_64-image = "manylinux_2_34"
87+
88+
[tool.cibuildwheel.linux]
89+
before-all = "yum install -y cmake"
90+
repair-wheel-command = "auditwheel repair --exclude libamulet_utils.so --exclude libamulet_nbt.so -w {dest_dir} {wheel}"
91+
92+
[tool.cibuildwheel.macos]
93+
repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} --ignore-missing-dependencies --exclude libamulet_utils.dylib --exclude libamulet_nbt.dylib -w {dest_dir} -v {wheel}"
94+
95+
[tool.cibuildwheel.windows]
96+
repair-wheel-command = "delvewheel repair --ignore-existing --exclude \"msvcp140.dll;amulet_utils.dll;amulet_nbt.dll\" -w {dest_dir} -v {wheel}"
97+
test-command = [
98+
"python -m venv venv_build",
99+
"venv_build\\Scripts\\pip install {wheel}[dev]",
100+
"venv_build\\Scripts\\python tools/compile_tests.py",
101+
"python -m unittest discover -s tests"
102+
]

requirements.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
AMULET_COMPILER_TARGET_REQUIREMENT = "==2.0"
66

7-
PYBIND11_REQUIREMENT = "==3.0.1"
7+
PYBIND11_REQUIREMENT = "==3.0.4"
88
AMULET_PYBIND11_EXTENSIONS_REQUIREMENT = "~=1.2.0.0a2"
99
AMULET_IO_REQUIREMENT = "~=2.0.0.0a0"
10-
AMULET_UTILS_REQUIREMENT = "~=1.1.4.0a"
11-
AMULET_ZLIB_REQUIREMENT = "~=1.0.9.0a0"
12-
AMULET_NBT_REQUIREMENT = "~=5.0.4.0a0"
10+
AMULET_UTILS_REQUIREMENT = "~=1.1.5.0a"
11+
AMULET_ZLIB_REQUIREMENT = "~=1.0.11.0a0"
12+
AMULET_NBT_REQUIREMENT = "~=5.0.5.0a0"
1313
NUMPY_REQUIREMENT = "~=2.0"
1414

1515
if os.environ.get("AMULET_PYBIND11_EXTENSIONS_REQUIREMENT", None):
@@ -47,9 +47,6 @@ def get_specifier_set(version_str: str) -> str:
4747
return f"~={version.major}.{version.minor}.{version.micro}.0{''.join(map(str, version.pre or ()))}"
4848

4949

50-
AMULET_COMPILER_VERSION_REQUIREMENT = get_compiler.main()
51-
52-
5350
try:
5451
import amulet.pybind11_extensions
5552
except ImportError:
@@ -90,7 +87,7 @@ def get_specifier_set(version_str: str) -> str:
9087

9188
def get_build_dependencies() -> list:
9289
return [
93-
f"amulet-compiler-version{AMULET_COMPILER_VERSION_REQUIREMENT}",
90+
f"amulet-compiler-version{get_compiler.main()}",
9491
f"pybind11{PYBIND11_REQUIREMENT}",
9592
f"amulet-pybind11-extensions{AMULET_PYBIND11_EXTENSIONS_REQUIREMENT}",
9693
f"amulet-io{AMULET_IO_REQUIREMENT}",
@@ -100,10 +97,10 @@ def get_build_dependencies() -> list:
10097
] * (not os.environ.get("AMULET_SKIP_COMPILE", None))
10198

10299

103-
def get_runtime_dependencies() -> list[str]:
100+
def get_runtime_dependencies(sdist: bool = False) -> list[str]:
104101
return [
105102
f"amulet-compiler-target{AMULET_COMPILER_TARGET_REQUIREMENT}",
106-
f"amulet-compiler-version{AMULET_COMPILER_VERSION_REQUIREMENT}",
103+
f"amulet-compiler-version{get_compiler.main(sdist)}",
107104
f"pybind11{PYBIND11_REQUIREMENT}",
108105
f"amulet-pybind11-extensions{AMULET_PYBIND11_EXTENSIONS_REQUIREMENT}",
109106
f"amulet-io{AMULET_IO_REQUIREMENT}",

setup.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def build_extension(self, ext: Extension) -> None:
4646

4747
platform_args = []
4848
if sys.platform == "win32":
49-
platform_args.extend(["-G", "Visual Studio 17 2022"])
49+
platform_args.extend(["-G", "Visual Studio 18 2026"])
5050
if sysconfig.get_platform() == "win-amd64":
5151
platform_args.extend(["-A", "x64"])
5252
elif sysconfig.get_platform() == "win32":
@@ -55,7 +55,7 @@ def build_extension(self, ext: Extension) -> None:
5555
platform_args.extend(["-A", "ARM64"])
5656
else:
5757
raise RuntimeError(f"Unsupported platform: {sysconfig.get_platform()}")
58-
platform_args.extend(["-T", "v143"])
58+
platform_args.extend(["-T", "v145"])
5959
elif sys.platform == "darwin":
6060
if platform.machine() == "arm64":
6161
platform_args.append("-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64")
@@ -99,5 +99,7 @@ def build_extension(self, ext: Extension) -> None:
9999
cmdclass=cmdclass,
100100
ext_modules=[Extension("amulet.core._amulet_core", [])]
101101
* (not os.environ.get("AMULET_SKIP_COMPILE", None)),
102-
install_requires=requirements.get_runtime_dependencies(),
102+
install_requires=requirements.get_runtime_dependencies(
103+
sys.argv[1] in ["egg_info", "sdist"]
104+
),
103105
)

src/amulet/core/__init__.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,15 @@
1111
def _init() -> None:
1212
import os
1313
import sys
14-
import ctypes
1514

1615
if os.environ.get("AMULET_SKIP_COMPILE", None):
1716
return
1817

19-
if sys.platform == "win32":
20-
lib_path = os.path.join(os.path.dirname(__file__), "amulet_core.dll")
21-
elif sys.platform == "darwin":
22-
lib_path = os.path.join(os.path.dirname(__file__), "libamulet_core.dylib")
23-
elif sys.platform == "linux":
24-
lib_path = os.path.join(os.path.dirname(__file__), "libamulet_core.so")
25-
else:
26-
raise RuntimeError(f"Unsupported platform {sys.platform}")
27-
2818
# Import dependencies
2919
import amulet.utils
3020
import amulet.zlib
3121
import amulet.nbt
3222

33-
# Load the shared library
34-
ctypes.cdll.LoadLibrary(lib_path)
35-
3623
from ._amulet_core import init
3724

3825
init(sys.modules[__name__])

0 commit comments

Comments
 (0)