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
42 changes: 23 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ jobs:
echo "HEAD_SHA=${{ github.sha }}" >> $GITHUB_ENV
fi

- name: Build wheel in Docker
- name: Build wheels in Docker
run: |
docker run --rm \
-v ${{ github.workspace }}:/workspace \
Expand All @@ -451,17 +451,18 @@ jobs:
set -euo pipefail
mv /src/conanprofile .

# Build the C++ project
# Build the C++ project once
export CMAKE_BUILD_PARALLEL_LEVEL=4
make build/Release/silo

# Build the wheel
rm -rf dist
uv build --wheel

# Repair wheel for manylinux compatibility
# Build wheels for all supported Python versions
mkdir -p wheelhouse
uv tool run auditwheel repair dist/*.whl -w wheelhouse/
for pyversion in 3.11 3.12 3.13 3.14; do
uv python install \$pyversion
rm -rf dist
uv build --wheel --python \$pyversion
uv tool run auditwheel repair dist/*.whl -w wheelhouse/
done
"

- name: Upload wheel as workflow artifact
Expand All @@ -488,17 +489,20 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

buildWheelsMacos:
name: Build wheel (macos-arm64)
runs-on: macos-15
name: Build wheel (macos-${{ matrix.arch }})
strategy:
matrix:
include:
- runner: macos-15
arch: arm64
- runner: macos-15-intel
arch: x86_64
runs-on: ${{ matrix.runner }}
permissions:
contents: write
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: "3.12"

- uses: astral-sh/setup-uv@v7

- name: Install Conan
Expand All @@ -508,17 +512,17 @@ jobs:
uses: actions/cache@v5
with:
path: ~/.conan2
key: conan-macos-arm64-${{ hashFiles('conanfile.py', 'Dockerfile_dependencies') }}
key: conan-macos-${{ matrix.arch }}-${{ hashFiles('conanfile.py', 'Dockerfile_dependencies') }}
restore-keys: |
conan-macos-arm64-
conan-macos-${{ matrix.arch }}-

- name: Build wheel
run: make build-wheel
- name: Build wheels for all supported Python versions
run: make build-wheels

- name: Upload wheel as workflow artifact
uses: actions/upload-artifact@v6
with:
name: wheel-macos-arm64
name: wheel-macos-${{ matrix.arch }}
path: wheelhouse/*.whl

- name: Determine release version
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ add_subdirectory(performance)
option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF)

if(BUILD_PYTHON_BINDINGS)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)

# Find Cython
execute_process(
Expand Down
31 changes: 18 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,25 @@ python-tests: ${DEPENDENCIES_FLAG}
uv pip install -q --no-build-isolation ".[test]"
.venv/bin/pytest python/tests -v

build-wheel: conanprofile

PYTHON_VERSIONS ?= 3.11 3.12 3.13 3.14

build-wheels: conanprofile
python3 ./build_with_conan.py --release
rm -rf dist
@if [ "$$(uname)" = "Darwin" ]; then \
_PYTHON_HOST_PLATFORM="macosx-15.0-$$(uname -m)" uv build --wheel; \
else \
uv build --wheel; \
fi
mkdir -p wheelhouse
@if [ "$$(uname)" = "Darwin" ]; then \
uv tool run --from delocate delocate-wheel -w wheelhouse/ dist/*.whl; \
else \
uv tool run auditwheel repair dist/*.whl -w wheelhouse/; \
fi
@for pyversion in $(PYTHON_VERSIONS); do \
echo; \
echo "--- Building wheel for Python $$pyversion ---"; \
uv python install $$pyversion; \
rm -rf dist; \
if [ "$$(uname)" = "Darwin" ]; then \
_PYTHON_HOST_PLATFORM="macosx-15.0-$$(uname -m)" uv build --wheel --python $$pyversion; \
uv tool run --from delocate delocate-wheel -w wheelhouse/ dist/*.whl; \
else \
uv build --wheel --python $$pyversion; \
uv tool run auditwheel repair dist/*.whl -w wheelhouse/; \
fi; \
done

all-tests: test e2e python-tests

Expand Down Expand Up @@ -122,4 +127,4 @@ full-clean: clean
rm -rf build

.PHONY:
full-clean clean clean-api e2e format format-cpp format-node check-format check-format-cpp check-format-node all test all-tests ci python-tests build-wheel
full-clean clean clean-api e2e format format-cpp format-node check-format check-format-cpp check-format-node all test all-tests ci python-tests build-wheels
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: C++",
]
dependencies = [
Expand Down
43 changes: 13 additions & 30 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,58 +60,41 @@ def _run_cmake(self):
# The directory containing this setup.py
source = os.path.dirname(os.path.abspath(__file__))

# Get setuptools build directories (following Arrow's pattern)
# Get setuptools build directories
build_cmd = self.get_finalized_command('build')
saved_cwd = os.getcwd()
build_temp = pjoin(saved_cwd, build_cmd.build_temp)
build_lib = pjoin(saved_cwd, build_cmd.build_lib)

if not os.path.isdir(build_temp):
self.mkpath(build_temp)

# Install directly to setuptools' build_lib directory
# This way setuptools finds the files without manual copying
install_prefix = pjoin(build_lib, "silodb")

# Configuration name (e.g., Debug, Release)
config_name = self.build_type.capitalize()

# Change to the build_temp directory
with changed_dir(build_temp):
# Find existing conan generators directory
# Try build/{config_name}/generators first, then build/{other_config}/generators
conan_generators_dir = None
for config in [config_name, 'Release', 'Debug']:
candidate = pjoin(source, "build", config, "generators")
if os.path.exists(candidate):
conan_generators_dir = candidate
break

if not conan_generators_dir:
raise RuntimeError(
"Conan dependencies not found. Please run the following first:\n"
f" mkdir -p build/{config_name} && cd build/{config_name}\n"
" conan install ../..\n"
" cmake ../.. -DBUILD_PYTHON_BINDINGS=OFF\n"
" cmake --build .\n"
"Then retry: pip install ."
)

print(f"-- Using conan dependencies from {conan_generators_dir}")
# Reuse the existing cmake build directory (populated by `make dependencies`)
# so that silolib is not recompiled for each Python version
build_dir = pjoin(source, "build", config_name)

if not os.path.isdir(build_dir):
self.mkpath(build_dir)

# Change to the build_dir directory
with changed_dir(build_dir):
# --- CONFIGURE ---
cmake_options = [
f'-DCMAKE_INSTALL_PREFIX={install_prefix}',
f'-DPython3_EXECUTABLE={sys.executable}',
# Explicitly provide include dir so CMake finds headers for
# python-build-standalone installs (used by uv) on Linux
f'-DPython3_INCLUDE_DIR={sysconfig.get_path("include")}',
f'-DCMAKE_BUILD_TYPE={config_name}',
f'-DCMAKE_PREFIX_PATH={conan_generators_dir}',
f'-DCMAKE_MODULE_PATH={conan_generators_dir}',
'-DBUILD_PYTHON_BINDINGS=ON',
# var ignored on other OSs
'-DCMAKE_OSX_DEPLOYMENT_TARGET=15.0',
Comment on lines 93 to 94
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting CMAKE_OSX_DEPLOYMENT_TARGET to 15.0 will make the wheels only compatible with macOS 15 Sequoia and later. This is quite restrictive and excludes users on macOS 14, 13, and earlier versions. Consider lowering this to a more widely compatible version like 11.0 or 12.0 to maximize compatibility across different macOS versions, especially for x86_64 builds which typically support older hardware. The comment says the var is "ignored on other OSs" but doesn't justify why 15.0 is required for macOS.

Suggested change
# var ignored on other OSs
'-DCMAKE_OSX_DEPLOYMENT_TARGET=15.0',
# var ignored on other OSs; 12.0 chosen to maximize macOS compatibility
'-DCMAKE_OSX_DEPLOYMENT_TARGET=12.0',

Copilot uses AI. Check for mistakes.
]

print(f"-- Running cmake to configure project in {build_temp}")
print(f"-- Running cmake to configure project in {build_dir}")
print(f"-- Will install to: {install_prefix}")
self.spawn(['cmake'] + cmake_options + [source])
Comment on lines +75 to 99
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When building wheels for multiple Python versions sequentially, each invocation of setup.py will run cmake configure in the same build/Release directory with different Python3_EXECUTABLE and Python3_INCLUDE_DIR values. This could lead to CMake cache conflicts where the second run might use cached values from the first run. Consider adding a mechanism to either clear the Python-specific CMake cache entries or use separate build directories for each Python version (e.g., build/Release-py311, build/Release-py312) while still reusing the compiled silolib.

Copilot uses AI. Check for mistakes.

Expand Down
Loading