Skip to content

Commit

Permalink
Added build_mac_wheel.sh script for building mac wheels
Browse files Browse the repository at this point in the history
  • Loading branch information
henryborchers committed Sep 5, 2024
1 parent fec9b70 commit 61eaee2
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 53 deletions.
60 changes: 7 additions & 53 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -557,31 +557,9 @@ def mac_wheels(){
],
retries: 3,
buildCmd: {
withEnv([
'_PYTHON_HOST_PLATFORM=macosx-10.9-x86_64',
'MACOSX_DEPLOYMENT_TARGET=10.9',
'ARCHFLAGS=-arch x86_64',
'UV_INDEX_STRATEGY=unsafe-best-match'
]){
sh(label: 'Building wheel',
script: """python${pythonVersion} -m venv venv
. ./venv/bin/activate
pip install uv
uv pip install wheel==0.37
uv pip install build delocate
python -m build --wheel --installer=uv
"""
)
findFiles(glob: 'dist/*.whl').each{
sh(label: 'Fixing up wheel',
script: """. ./venv/bin/activate
pip list
delocate-listdeps --depending ${it.path}
delocate-wheel -w fixed_wheels --require-archs x86_64 --verbose ${it.path}
"""
)
}
}
sh(label: 'Building wheel',
script: "contrib/build_mac_wheel.sh . --venv_path=./venv"
)
},
post:[
cleanup: {
Expand Down Expand Up @@ -657,34 +635,10 @@ def mac_wheels(){
label: "mac && python${pythonVersion} && m1",
],
buildCmd: {
// Taken from cibuildwheel source code
// https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/macos.py
//
// # macOS 11 is the first OS with arm64 support, so the wheels
// # have that as a minimum.
withEnv([
'_PYTHON_HOST_PLATFORM=macosx-11.0-arm64',
'MACOSX_DEPLOYMENT_TARGET=11.0',
'ARCHFLAGS=-arch arm64',
'UV_INDEX_STRATEGY=unsafe-best-match'
]) {
sh(label: 'Building wheel',
script: """python${pythonVersion} -m venv venv
. ./venv/bin/activate
pip install uv
uv pip install wheel==0.37
uv pip install build delocate
python -m build --wheel --installer=uv
"""
)
findFiles(glob: 'dist/*.whl').each{
sh(label: 'Fixing up wheel',
script: """./venv/bin/delocate-listdeps --depending ${it.path}
./venv/bin/delocate-wheel -w fixed_wheels --require-archs arm64 --verbose ${it.path}
"""
)
}
}
sh(label: 'Building wheel',
script: "contrib/build_mac_wheel.sh . --venv_path=./venv"
)
}
},
post:[
cleanup: {
Expand Down
10 changes: 10 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ ____________

This generates a whl and tar.gz file in the ./dist/ directory and can be used to install into your Python
environment.

Building Portable Python wheels for Mac
---------------------------------------

Since this package links to Tesseract library, to make sure that these files are generated in a portable manner and
will run on other machines, please use the script (contrib/build_mac_wheel.sh) provided to generate them.

```console
$ contrib/build_mac_wheel .
```
144 changes: 144 additions & 0 deletions contrib/build_mac_wheel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/usr/bin/env bash

set -e

DEFAULT_PYTHON_VENV="./wheel_builder_venv"

remove_venv(){
if [ -d $1 ]; then
echo "removing $1"
rm -r $1
fi
}

generate_venv(){
virtual_env=$1
trap "remove_venv $virtual_env" ERR SIGINT SIGTERM
python3 -m venv $virtual_env
. $virtual_env/bin/activate
pip install uv
uv pip install wheel==0.37
uv pip install build delocate
}

generate_wheel(){
virtual_env=$1
. $virtual_env/bin/activate

# Get the processor type
processor_type=$(uname -m)

# Set the compiling variables based on the processor results
#
# The values are taken from cibuildwheel source code
# https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/macos.py
#
# macOS 11 is the first OS with arm64 support, so the wheels
# have that as a minimum.

if [ "$processor_type" == "arm64" ]; then
_PYTHON_HOST_PLATFORM='macosx-11.0-arm64'
MACOSX_DEPLOYMENT_TARGET='11.0'
ARCHFLAGS='-arch arm64'
REQUIRED_ARCH='arm64'
elif [ "$processor_type" == "x86_64" ]; then
_PYTHON_HOST_PLATFORM='macosx-10.9-x86_64'
MACOSX_DEPLOYMENT_TARGET='10.9'
ARCHFLAGS='-arch x86_64'
REQUIRED_ARCH='x86_64'
else
echo "Unknown processor type: $processor_type"
fi

out_temp_wheels_dir=$(mktemp -d /tmp/python_wheels.XXXXXX)
output_path="./dist"
trap "rm -rf $out_temp_wheels_dir" ERR SIGINT SIGTERM RETURN
UV_INDEX_STRATEGY=unsafe-best-match _PYTHON_HOST_PLATFORM=$_PYTHON_HOST_PLATFORM MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET ARCHFLAGS=$ARCHFLAGS python -m build --wheel --installer=uv --outdir=$out_temp_wheels_dir
pattern="$out_temp_wheels_dir/*.whl"
files=( $pattern )
undelocate_wheel="${files[0]}"

echo ""
echo "================================================================================"
echo "${undelocate_wheel} is linked to the following:"
delocate-listdeps --depending "${undelocate_wheel}"
echo ""
echo "================================================================================"
delocate-wheel -w $output_path --require-archs $REQUIRED_ARCH --verbose "$undelocate_wheel"
}

print_usage(){
echo "Usage: $0 project_root [--venv_path optional_path]"
}

show_help() {
print_usage
echo
echo "Arguments:"
echo " project_root Path to Python project containing pyproject.toml file."
echo " --venv_path[=path] Path used to install build tools. Defaults to '$DEFAULT_PYTHON_VENV'."
echo " --help, -h Display this help message."
}


check_args(){
if [[ -f "$project_root" ]]; then
echo "error: project_root should point to a directory not a file"
print_usage
exit
fi
if [[ ! -f "$project_root/pyproject.toml" ]]; then
echo "error: $project_root contains no pyproject.toml"
exit
fi
}

# Check if the help flag is provided
for arg in "$@"; do
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
show_help
exit 0
fi
done

# Check if the project_root argument is provided
if [ -z "$1" ]; then
print_usage
exit 1
fi

# Assign the positional argument to a variable
project_root=$1

# Default path value
venv_path=$DEFAULT_PYTHON_VENV

# Parse optional arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--venv_path=*)
venv_path="${1#*=}"
shift
;;
--venv_path)
venv_path="$2"
shift 2
;;
*)
shift
;;
esac
done

# Output the values

check_args

build_virtual_env=$venv_path
if [[ ! -f "$build_virtual_env/bin/python" ]]; then
generate_venv $build_virtual_env
else
echo "Using existing venv: $build_virtual_env"
fi

generate_wheel $build_virtual_env $project_root

0 comments on commit 61eaee2

Please sign in to comment.