Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/build-wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build wheels

on:
push:
branches: [ master, main ]
tags: [ v* ]
pull_request:
branches: [ master, main ]

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, macos-14] # macos-14 is Apple Silicon

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.8'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pybind11>=2.11.0 setuptools>=40.6.0

- name: Build wheels
uses: pypa/[email protected]
env:
# Skip 32-bit builds and older Python versions
CIBW_SKIP: "*-win32 *-manylinux_i686 pp* cp36-*"
# Apple Silicon specific settings
CIBW_ARCHS_MACOS: "x86_64 arm64"
# Ensure we have CMake 3.18+ and pybind11 2.11+
CIBW_BEFORE_ALL_MACOS: "brew install cmake && pip install 'pybind11>=2.11.0'"
CIBW_BEFORE_ALL_LINUX: |
if command -v yum > /dev/null; then
yum install -y cmake3;
elif command -v apt > /dev/null; then
apt update && apt install -y cmake;
elif command -v zypper > /dev/null; then
zypper install -y cmake;
else
echo "Unsupported package manager. Please install cmake manually." && exit 1;
fi
pip install 'pybind11>=2.11.0'
CIBW_BEFORE_ALL_WINDOWS: "pip install 'pybind11>=2.11.0'"
# Test that the wheels work
CIBW_TEST_COMMAND: "python -c \"import SymSpellCppPy; symspell = SymSpellCppPy.SymSpell(); print('✅ Import and basic functionality test passed')\""

- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl

upload_pypi:
needs: [build_wheels]
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/download-artifact@v3
with:
name: artifact
path: dist

- uses: pypa/[email protected]
with:
password: ${{ secrets.PYPI_API_TOKEN }}
28 changes: 23 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.18)
project(SymSpellCppPy)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_BUILD_TYPE "Release")

# Apple Silicon specific optimizations
if(APPLE AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
set(CMAKE_OSX_ARCHITECTURES "arm64")
message(STATUS "Detected Apple Silicon, enabling arm64 optimizations")
endif()

option(BUILD_FOR_PYTHON "Build for Python" OFF)
option(BUILD_FOR_TEST "Build Tests" ON)

Expand All @@ -16,17 +22,29 @@ if (BUILD_FOR_PYTHON)
set(CMAKE_BUILD_TYPE "Release")
Include(FetchContent)

# Use newer pybind11 version with better CMake support
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG v2.10.4)
GIT_TAG v2.11.1)
FetchContent_MakeAvailable(pybind11)
pybind11_add_module(SymSpellCppPy MODULE SymSpellCppPy.cpp)
target_sources(SymSpellCppPy PRIVATE library.cpp library.h)
target_link_libraries(SymSpellCppPy PRIVATE SymSpellCpp)
target_compile_options(SymSpellCppPy PRIVATE
$<$<CONFIG:Release>:-O3 -DNDEBUG -march=native -mtune=native -fvisibility=hidden
-flto -ffat-lto-objects>)

# Platform-specific compile options
if(APPLE AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
# Apple Silicon optimizations
target_compile_options(SymSpellCppPy PRIVATE
$<$<CONFIG:Release>:-O3 -DNDEBUG -march=armv8.4-a -fvisibility=hidden
-flto -ffat-lto-objects>)
else()
# Standard x86_64 optimizations
target_compile_options(SymSpellCppPy PRIVATE
$<$<CONFIG:Release>:-O3 -DNDEBUG -march=native -mtune=native -fvisibility=hidden
-flto -ffat-lto-objects>)
endif()

message(STATUS "Build for Python = " ${BUILD_FOR_PYTHON})
else ()
Include(FetchContent)
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
setuptools
pybind11
setuptools>=40.6.0
pybind11>=2.11.0
recommonmark
sphinx_rtd_theme
31 changes: 25 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ def run(self):
raise RuntimeError("CMake must be installed to build the following extensions: " +
", ".join(e.name for e in self.extensions))

cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1))

if platform.system() == "Windows":
cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1))
if cmake_version < '3.1.0':
raise RuntimeError("CMake >= 3.1.0 is required on Windows")
else:
if cmake_version < '3.18.0':
raise RuntimeError("CMake >= 3.18.0 is required for Apple Silicon support. "
"Please update CMake by visiting https://cmake.org/download/ or using your system's package manager.")

for ext in self.extensions:
self.build_extension(ext)
Expand All @@ -58,6 +63,10 @@ def build_extension(self, ext):
cmake_args += ["-DCMAKE_BUILD_WITH_INSTALL_RPATH=TRUE"]
cmake_args += ["-DCMAKE_INSTALL_RPATH={}".format("$ORIGIN")]

# Apple Silicon specific settings
if platform.system() == "Darwin" and platform.machine() == "arm64":
cmake_args += ["-DCMAKE_OSX_ARCHITECTURES=arm64"]

if platform.system() == "Windows":
cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)]
if sys.maxsize > 2 ** 32:
Expand All @@ -70,6 +79,11 @@ def build_extension(self, ext):
env = os.environ.copy()
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''),
self.distribution.get_version())

# Add Apple Silicon optimization flags
if platform.system() == "Darwin" and platform.machine() == "arm64":
env['CXXFLAGS'] = '{} -mcpu=apple-a14'.format(env.get('CXXFLAGS', ''))

if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env)
Expand All @@ -88,7 +102,14 @@ def build_extension(self, ext):
test_suite="tests/SymSpellCppPyTest.py",
ext_modules=[CMakeExtension('SymSpellCppPy')],
cmdclass=versioneer.get_cmdclass(dict(build_ext=CMakeBuild)),
python_requires=">=3.4",
python_requires=">=3.7",
install_requires=[
"pybind11>=2.11.0",
],
setup_requires=[
"pybind11>=2.11.0",
"setuptools>=40.6.0",
],
zip_safe=False,
url="https://github.com/viig99/SymSpellCppPy",
classifiers=[
Expand All @@ -98,13 +119,11 @@ def build_extension(self, ext):
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11"
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12"
]
)
Loading