Skip to content

Commit 47f93e9

Browse files
authored
[v5] Updates and fixes to the Python wheel builder workflow (#2440)
1 parent eb5b24b commit 47f93e9

File tree

4 files changed

+125
-20
lines changed

4 files changed

+125
-20
lines changed

.github/workflows/python-publish-release.yml

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,35 @@ jobs:
1818

1919
- name: Set up QEMU
2020
if: runner.os == 'Linux'
21-
uses: docker/setup-qemu-action@v2
21+
uses: docker/setup-qemu-action@v3
2222
with:
2323
platforms: all
2424

2525
- name: Build wheels
26-
uses: pypa/cibuildwheel@v2.16.5
26+
uses: pypa/cibuildwheel@v2.20.0
2727
env:
2828
CIBW_ARCHS_MACOS: "x86_64 universal2 arm64"
29-
CIBW_ARCHS_LINUX: "x86_64 i686 aarch64" # ppc64le s390x really slow
30-
CIBW_ARCHS_WINDOWS: "AMD64 x86" # ARM64 Seems ARM64 will rebuild amd64 wheel for unknow reason.
29+
CIBW_ARCHS_LINUX: "x86_64 i686" # ppc64le s390x really slow
30+
CIBW_ARCHS_WINDOWS: "AMD64" # ARM64 Seems ARM64 will rebuild amd64 wheel for unknow reason.
3131
CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-*"
3232
CIBW_SKIP: ""
3333
with:
3434
package-dir: bindings/python
3535

36-
- uses: actions/upload-artifact@v3
36+
- uses: actions/upload-artifact@v4
3737
with:
3838
path: ./wheelhouse/*.whl
39+
name: artifacts-${{ matrix.os }}
40+
41+
- name: Check binaries (Windows)
42+
if: matrix.os == 'windows-latest'
43+
run: |
44+
python3.exe suite/check_wheel_bin_arch.py ./wheelhouse/
45+
46+
- name: Check binaries (Unix)
47+
if: matrix.os != 'windows-latest'
48+
run: |
49+
./suite/check_wheel_bin_arch.py ./wheelhouse/
3950
4051
make_sdist:
4152
name: Make SDist
@@ -51,7 +62,7 @@ jobs:
5162
cd bindings/python
5263
pipx run build --sdist
5364
54-
- uses: actions/upload-artifact@v3
65+
- uses: actions/upload-artifact@v4
5566
with:
5667
path: bindings/python/dist/*.tar.gz
5768

@@ -62,18 +73,10 @@ jobs:
6273
permissions:
6374
id-token: write
6475
steps:
65-
- uses: actions/download-artifact@v3
76+
- uses: actions/download-artifact@v4
6677
with:
67-
name: artifact
6878
path: dist
6979

70-
# - name: Publish distribution 📦 to test PyPI
71-
# uses: pypa/gh-action-pypi-publish@release/v1
72-
# with:
73-
# user: __token__
74-
# password: ${{ secrets.test_pypi_pass }}
75-
# repository_url: https://test.pypi.org/legacy/
76-
7780
- name: Publish distribution 📦 to PyPI
7881
if: ${{ success() }}
7982
uses: pypa/gh-action-pypi-publish@release/v1

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ endif()
3636
# Don't edit the makefile!
3737
option(BUILD_SHARED_LIBS "Build shared library" OFF)
3838
option(CAPSTONE_BUILD_STATIC_RUNTIME "Embed static runtime" ${BUILD_SHARED_LIBS})
39+
option(CAPSTONE_BUILD_MACOS_THIN "Disable universal2 builds on macOS" OFF)
3940
option(CAPSTONE_BUILD_DIET "Build diet library" OFF)
4041
option(CAPSTONE_BUILD_TESTS "Build tests" ${PROJECT_IS_TOP_LEVEL})
4142
option(CAPSTONE_BUILD_CSTOOL "Build cstool" ${PROJECT_IS_TOP_LEVEL})
@@ -48,6 +49,23 @@ option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL})
4849
set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH TRICORE)
4950
set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH TriCore)
5051

52+
# If building for OSX it's best to allow CMake to handle building both architectures
53+
if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
54+
# The cibuildwheel on Github Actions sets this env variable
55+
# with the architecture flags it wants to build for.
56+
if(DEFINED ENV{ARCHFLAGS})
57+
if("$ENV{ARCHFLAGS}" STREQUAL "-arch arm64 -arch x86_64")
58+
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
59+
elseif("$ENV{ARCHFLAGS}" STREQUAL "-arch arm64")
60+
set(CMAKE_OSX_ARCHITECTURES "arm64")
61+
elseif("$ENV{ARCHFLAGS}" STREQUAL "-arch x86_64")
62+
set(CMAKE_OSX_ARCHITECTURES "x86_64")
63+
endif()
64+
else()
65+
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
66+
endif()
67+
endif()
68+
5169
list(LENGTH SUPPORTED_ARCHITECTURES count)
5270
math(EXPR count "${count}-1")
5371
# create options controlling whether support for a particular architecture is needed

bindings/python/setup.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,20 @@ def build_libraries():
134134

135135
os.chdir(BUILD_DIR)
136136

137-
# platform description refers at https://docs.python.org/2/library/sys.html#sys.platform
138-
if SYSTEM == "win32":
137+
# platform description refers at https://docs.python.org/3/library/sys.html#sys.platform
138+
if SYSTEM == "win32" or SYSTEM == 'darwin':
139139
# Windows build: this process requires few things:
140140
# - CMake + MSVC installed
141141
# - Run this command in an environment setup for MSVC
142-
if not os.path.exists("build"): os.mkdir("build")
142+
if not os.path.exists("build"):
143+
os.mkdir("build")
143144
os.chdir("build")
144-
# Only build capstone.dll
145-
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "NMake Makefiles" ..')
145+
print("Build Directory: {}\n".format(os.getcwd()))
146+
# Only build capstone.dll / libcapstone.dylib
147+
if SYSTEM == "win32":
148+
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "NMake Makefiles" ..')
149+
else:
150+
os.system('cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCAPSTONE_BUILD_TESTS=OFF -DCAPSTONE_BUILD_CSTOOL=OFF -G "Unix Makefiles" ..')
146151
os.system("cmake --build .")
147152
else: # Unix incl. cygwin
148153
os.system("CAPSTONE_BUILD_CORE_ONLY=yes bash ./make.sh")

suite/check_wheel_bin_arch.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
# Copyright © 2024 Rot127 <[email protected]>
3+
# SPDX-License-Identifier: BSD-3
4+
5+
import logging as log
6+
import subprocess as sp
7+
import re
8+
import os
9+
import sys
10+
from pathlib import Path
11+
12+
if len(sys.argv) != 2:
13+
print(f"{sys.argv[0]} <wheel_dir>")
14+
exit(-1)
15+
16+
log.basicConfig(
17+
level=log.INFO,
18+
stream=sys.stdout,
19+
format="%(levelname)-5s - %(message)s",
20+
force=True,
21+
)
22+
23+
archs = {
24+
"universal2": ["x86_64", "arm64"],
25+
"x86_64": [r"x86[_-]64"],
26+
"arm64": ["arm64"],
27+
"aarch64": ["ARM aarch64"],
28+
"i686": ["Intel 80386"],
29+
"win32": [r"INVALID"],
30+
"amd64": [r"x86[_-]64"],
31+
}
32+
33+
filename = {
34+
"macosx": "libcapstone.dylib",
35+
"manylinux": "libcapstone.so",
36+
"win": "capstone.dll",
37+
}
38+
39+
success = True
40+
wheel_seen = False
41+
for root, dir, files in os.walk(sys.argv[1]):
42+
for file in files:
43+
f = Path(root).joinpath(file)
44+
if f.suffix != ".whl":
45+
continue
46+
wheel_seen = True
47+
target = re.search(r"py3-none-(.+).whl", f"{f}").group(1)
48+
platform = re.search("^(win|manylinux|macosx)", target).group(1)
49+
50+
arch = re.search(
51+
"(universal2|x86_64|arm64|aarch64|i686|win32|amd64)$", target
52+
).group(1)
53+
log.info(f"Target: {target} - Platform: {platform} - Arch: {archs[arch]}")
54+
55+
out_dir = f"{platform}__{arch}"
56+
sp.run(["unzip", "-q", f"{f}", "-d", out_dir], check=True)
57+
lib_path = Path(out_dir).joinpath(f"capstone/lib/{filename[platform]}")
58+
result = sp.run(["file", "-b", f"{lib_path}"], capture_output=True, check=True)
59+
stdout = result.stdout.decode("utf8").strip()
60+
if any([not re.search(a, stdout) for a in archs[arch]]):
61+
success = False
62+
log.error(f"The wheel '{file}' is not compiled for '{archs[arch]}'.")
63+
log.error(f"Binary is: {stdout}")
64+
print()
65+
else:
66+
log.info(f"OK: Arch: {arch} - {lib_path}")
67+
log.info(f"Binary is: {stdout}")
68+
log.info(f"Delete {out_dir}")
69+
print()
70+
os.system(f"rm -r {out_dir}")
71+
break
72+
73+
if not wheel_seen:
74+
log.error("No wheel was checked.")
75+
exit(-1)
76+
77+
if not success:
78+
log.error("Binary files are compiled for the wrong architecture.")
79+
exit(-1)

0 commit comments

Comments
 (0)