@@ -12,6 +12,14 @@ set -ex
1212# Setup conda environment. Defaults to Python 3.10.
1313setup_conda_environment () {
1414 local python_version=${1:- 3.10}
15+
16+ # Check if we're in a manylinux container (no conda)
17+ if [[ -d /opt/python ]] && [[ ! -x " $( command -v conda) " ]]; then
18+ echo " Detected manylinux environment, using system Python instead of conda..."
19+ setup_manylinux_python " ${python_version} "
20+ return
21+ fi
22+
1523 echo " Setting up conda environment with Python ${python_version} ..."
1624 conda create -n venv python=" ${python_version} " -y
1725 conda activate venv
@@ -20,6 +28,33 @@ setup_conda_environment() {
2028 python -m pip install --upgrade pip
2129}
2230
31+ # Setup Python in manylinux container (no conda available)
32+ setup_manylinux_python () {
33+ local python_version=${1:- 3.10}
34+ echo " Setting up manylinux Python ${python_version} ..."
35+
36+ # Map Python version to manylinux cp version
37+ case " ${python_version} " in
38+ 3.10) PYTHON_DIR=" /opt/python/cp310-cp310" ;;
39+ 3.11) PYTHON_DIR=" /opt/python/cp311-cp311" ;;
40+ 3.12) PYTHON_DIR=" /opt/python/cp312-cp312" ;;
41+ 3.13) PYTHON_DIR=" /opt/python/cp313-cp313" ;;
42+ * ) echo " Unsupported Python version: ${python_version} " ; return 1 ;;
43+ esac
44+
45+ if [[ ! -d " ${PYTHON_DIR} " ]]; then
46+ echo " ERROR: Python directory ${PYTHON_DIR} not found"
47+ return 1
48+ fi
49+
50+ export PATH=" ${PYTHON_DIR} /bin:${PATH} "
51+ export PYTHON_BIN=" ${PYTHON_DIR} /bin/python"
52+
53+ echo " Using Python from: ${PYTHON_DIR} "
54+ python --version
55+ python -m pip install --upgrade pip
56+ }
57+
2358# Install system-level dependencies
2459install_system_dependencies () {
2560 echo " Installing system dependencies..."
@@ -227,3 +262,109 @@ run_test_groups() {
227262 fi
228263 set -e
229264}
265+
266+ # Retag wheels with manylinux platform tags
267+ #
268+ # When building wheels with `setup.py bdist_wheel`, the wheel is tagged with the
269+ # generic platform tag (e.g., "linux_x86_64", "linux_aarch64"). However, PyPI
270+ # requires proper manylinux tags (e.g., "manylinux2014_x86_64") to indicate
271+ # compatibility with the manylinux standard. Simply renaming the .whl file is
272+ # insufficient because the platform tag is also stored in the WHEEL metadata file
273+ # inside the wheel archive.
274+ #
275+ # This function properly retags wheels by:
276+ # 1. Unpacking the wheel archive
277+ # 2. Modifying the "Tag:" field in the .dist-info/WHEEL metadata file
278+ # 3. Repacking the wheel with the updated metadata and correct filename
279+ #
280+ # The `wheel pack` command automatically regenerates the RECORD file with updated
281+ # hashes, ensuring wheel integrity. This is similar to how PyTorch does it in their
282+ # manywheel build scripts (see pytorch/.ci/manywheel/build_common.sh).
283+ #
284+ # Usage: retag_wheel_platform <platform_tag> [wheel_dir]
285+ # platform_tag: Target platform (e.g., "manylinux2014_x86_64", "manylinux2014_aarch64")
286+ # wheel_dir: Directory containing wheels (defaults to "dist")
287+ #
288+ # Example:
289+ # retag_wheel_platform "manylinux2014_x86_64"
290+ # retag_wheel_platform "manylinux2014_aarch64" "build/wheels"
291+ retag_wheel_platform () {
292+ local platform_tag=" ${1} "
293+ local wheel_dir=" ${2:- dist} "
294+
295+ if [[ -z " $platform_tag " ]]; then
296+ echo " Error: platform_tag is required"
297+ echo " Usage: retag_wheel_platform <platform_tag> [wheel_dir]"
298+ return 1
299+ fi
300+
301+ if [[ ! -d " $wheel_dir " ]]; then
302+ echo " Error: wheel directory '$wheel_dir ' does not exist"
303+ return 1
304+ fi
305+
306+ echo " Retagging wheels in '$wheel_dir ' with platform tag: $platform_tag "
307+
308+ # Install wheel tool if not present
309+ pip install -q wheel
310+
311+ local wheel_count=0
312+ for whl in " $wheel_dir " /* .whl; do
313+ if [[ ! -f " $whl " ]]; then
314+ continue
315+ fi
316+
317+ wheel_count=$(( wheel_count + 1 ))
318+ echo " Processing: $( basename " $whl " ) "
319+
320+ # Unpack the wheel
321+ wheel unpack " $whl " -d " $wheel_dir "
322+ local whl_dir=$( find " $wheel_dir " -maxdepth 1 -type d -name " $( basename " $whl " .whl) " -print -quit)
323+
324+ if [[ -n " $whl_dir " && -d " $whl_dir " ]]; then
325+ # Find and modify the WHEEL metadata file
326+ local wheel_file=$( find " $whl_dir " -name " WHEEL" -type f)
327+
328+ if [[ -f " $wheel_file " ]]; then
329+ echo " Updating WHEEL metadata: $wheel_file "
330+
331+ # Replace platform tag based on target
332+ case " $platform_tag " in
333+ manylinux* _x86_64)
334+ sed -i ' s/Tag:.*linux_x86_64/Tag: py3-none-' " $platform_tag " ' /g' " $wheel_file "
335+ ;;
336+ manylinux* _aarch64)
337+ sed -i ' s/Tag:.*linux_aarch64/Tag: py3-none-' " $platform_tag " ' /g' " $wheel_file "
338+ ;;
339+ * )
340+ echo " Warning: Unknown platform tag pattern '$platform_tag ', attempting generic replacement"
341+ sed -i ' s/Tag: \(.*\)-linux_[^-]*/Tag: \1-' " $platform_tag " ' /g' " $wheel_file "
342+ ;;
343+ esac
344+ else
345+ echo " Warning: WHEEL file not found in unpacked wheel"
346+ fi
347+
348+ # Repack the wheel with new platform tag
349+ echo " Repacking wheel..."
350+ wheel pack " $whl_dir " -d " $wheel_dir " > /dev/null
351+
352+ # Clean up unpacked directory
353+ rm -rf " $whl_dir "
354+ fi
355+
356+ # Remove original wheel
357+ rm " $whl "
358+ echo " ✓ Retagged: $( basename " $whl " ) "
359+ done
360+
361+ if [[ $wheel_count -eq 0 ]]; then
362+ echo " Warning: No wheels found in '$wheel_dir '"
363+ return 1
364+ fi
365+
366+ echo " ✓ Successfully retagged $wheel_count wheel(s)"
367+ echo " Final wheels:"
368+ ls -lh " $wheel_dir " /* .whl
369+ }
370+
0 commit comments