diff --git a/.github/workflows/build-wheel.yml b/.github/workflows/build-wheel.yml index 78f53b34..832b7659 100644 --- a/.github/workflows/build-wheel.yml +++ b/.github/workflows/build-wheel.yml @@ -64,12 +64,16 @@ jobs: /opt/python/cp310-cp310/bin/pip install -r requirements.txt -r requirements-dev.txt && /opt/python/cp310-cp310/bin/pip install toml && C2PA_LIBS_PLATFORM=\"${{ format('{0}', inputs.architecture == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu') }}\" /opt/python/cp310-cp310/bin/python scripts/download_artifacts.py $C2PA_VERSION && + /opt/python/cp310-cp310/bin/python -c \"import sys; sys.path.insert(0, '/io'); from setup import copy_platform_libraries; copy_platform_libraries('${{ format('{0}', inputs.architecture == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu') }}', clean_first=True)\" && + echo '[bdist_wheel]' > /io/setup.cfg && + echo 'plat-name = $PLATFORM_TAG' >> /io/setup.cfg && for PYBIN in /opt/python/cp3{10,11}-*/bin; do - \${PYBIN}/pip install --upgrade pip wheel && + \${PYBIN}/pip install --upgrade pip wheel build && \${PYBIN}/pip install toml==0.10.2 && \${PYBIN}/pip install setuptools==68.0.0 && - CFLAGS=\"-I/opt/python/cp310-cp310/include/python3.10\" LDFLAGS=\"-L/opt/python/cp310-cp310/lib\" \${PYBIN}/python setup.py bdist_wheel --plat-name $PLATFORM_TAG + cd /io && \${PYBIN}/python -m build --wheel done && + rm -f /io/setup.cfg && rm -f /io/dist/*-linux_*.whl " @@ -101,7 +105,7 @@ jobs: # Install dependencies pip install -r requirements.txt pip install -r requirements-dev.txt - pip install wheel + pip install wheel build pip install twine # Download native artifacts @@ -112,11 +116,24 @@ jobs: Write-Host "Artifacts directory contents:" Get-ChildItem -Recurse -Path artifacts + + # Copy libraries to package directory + python -c "import sys; sys.path.insert(0, '.'); from setup import copy_platform_libraries; copy_platform_libraries('x86_64-pc-windows-msvc', clean_first=True)" + Write-Host "src/c2pa/libs directory contents:" Get-ChildItem -Recurse -Path src/c2pa/libs - # Build wheel - python setup.py bdist_wheel --plat-name win_amd64 + # Create setup.cfg to specify platform-specific wheel + @" + [bdist_wheel] + plat-name = win_amd64 + "@ | Out-File -FilePath setup.cfg -Encoding utf8 + + # Build wheel using modern build tool + python -m build --wheel + + # Clean up setup.cfg + Remove-Item setup.cfg -ErrorAction SilentlyContinue # Verify wheel structure twine check dist/* @@ -132,9 +149,21 @@ jobs: # Install dependencies pip install -r requirements.txt pip install -r requirements-dev.txt - pip install wheel + pip install wheel build pip install twine + # Determine target platform for library copying + if [ "${{ inputs.architecture }}" = "universal2" ]; then + RUST_PLATFORM="universal-apple-darwin" + elif [ "${{ inputs.architecture }}" = "arm64" ]; then + RUST_PLATFORM="aarch64-apple-darwin" + elif [ "${{ inputs.architecture }}" = "x86_64" ]; then + RUST_PLATFORM="x86_64-apple-darwin" + else + echo "Unknown architecture: ${{ inputs.architecture }}" + exit 1 + fi + # Download native artifacts for the target architecture if [ "${{ inputs.architecture }}" = "universal2" ]; then python scripts/download_artifacts.py $C2PA_VERSION universal2 @@ -162,15 +191,20 @@ jobs: echo "Building wheel for architecture: ${{ inputs.architecture }}" echo "Using platform name: $PLATFORM_NAME" - # Build wheel with appropriate platform name - python setup.py bdist_wheel --plat-name $PLATFORM_NAME + # Copy libraries to package directory + python -c "import sys; sys.path.insert(0, '.'); from setup import copy_platform_libraries; copy_platform_libraries('$RUST_PLATFORM', clean_first=True)" + + # Create setup.cfg to specify platform for bdist_wheel + cat > setup.cfg << EOF + [bdist_wheel] + plat-name = $PLATFORM_NAME + EOF + + # Build wheel using modern build tool + python -m build --wheel - # Rename wheel to ensure unique filename - cd dist - for wheel in *.whl; do - mv "$wheel" "${wheel/$PLATFORM_NAME/$PLATFORM_NAME}" - done - cd .. + # Clean up setup.cfg + rm -f setup.cfg # Verify wheel structure echo "Verifying wheels using twine check" diff --git a/docs/project-contributions.md b/docs/project-contributions.md index c3affcb4..ee0e41bd 100644 --- a/docs/project-contributions.md +++ b/docs/project-contributions.md @@ -1,4 +1,4 @@ -# Contributing to the project +# Contributing to the project The information in this page is primarily for those who wish to contribute to the c2pa-python library project itself, rather than those who simply wish to use it in an application. For general contribution guidelines, see [CONTRIBUTING.md](../CONTRIBUTING.md). diff --git a/setup.py b/setup.py index 489472c1..a9fe970e 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ from setuptools import setup, find_namespace_packages import sys +import os import platform import shutil from pathlib import Path @@ -164,86 +165,34 @@ def find_available_platforms(): return available_platforms -# For development installation +# For development installation - copy libraries automatically +# When using pip install -e . or pip install ., this will copy the libraries if 'develop' in sys.argv or 'install' in sys.argv: current_platform = get_platform_identifier() print("Installing in development mode for platform ", current_platform) copy_platform_libraries(current_platform) -# For wheel building (both bdist_wheel and build) -if 'bdist_wheel' in sys.argv or 'build' in sys.argv: - # Check if we're building for a specific architecture - # This is mostly to support macOS wheel builds - target_arch = None - for i, arg in enumerate(sys.argv): - if arg == '--plat-name': - if i + 1 < len(sys.argv): - plat_name = sys.argv[i + 1] - if 'arm64' in plat_name: - target_arch = 'arm64' - elif 'x86_64' in plat_name: - target_arch = 'x86_64' - elif 'universal2' in plat_name: - target_arch = 'universal2' - break - - # Get the platform identifier for the target architecture - target_platform = get_platform_identifier(target_arch) - print(f"Building wheel for target platform: {target_platform}") - - # Check if we have libraries for this platform - platform_dir = ARTIFACTS_DIR / target_platform - if not platform_dir.exists() or not any(platform_dir.iterdir()): - print(f"Warning: No libraries found for platform {target_platform}") - print("Available platforms:") - for platform_name in find_available_platforms(): - print(f" - {platform_name}") - - # Copy libraries for the target platform - try: - copy_platform_libraries(target_platform, clean_first=True) - - # Build the wheel - setup( - name=PACKAGE_NAME, - version=VERSION, - package_dir={"": "src"}, - packages=find_namespace_packages(where="src"), - include_package_data=True, - package_data={ - "c2pa": ["libs/*"], - }, - classifiers=[ - "Programming Language :: Python :: 3", - get_platform_classifier(target_platform), - ], - python_requires=">=3.10", - long_description=open("README.md").read(), - long_description_content_type="text/markdown", - license="MIT OR Apache-2.0", - ) - finally: - # Clean up - if PACKAGE_LIBS_DIR.exists(): - shutil.rmtree(PACKAGE_LIBS_DIR) - sys.exit(0) - -# For sdist and development installation -setup( - name=PACKAGE_NAME, - version=VERSION, - package_dir={"": "src"}, - packages=find_namespace_packages(where="src"), - include_package_data=True, - package_data={ - "c2pa": ["libs/*"], # Include all files in libs directory - }, - classifiers=[ - "Programming Language :: Python :: 3", - get_platform_classifier(get_current_platform()), - ], - python_requires=">=3.10", - long_description=open("README.md").read(), - long_description_content_type="text/markdown", - license="MIT OR Apache-2.0", -) \ No newline at end of file +# Only call setup() if we're being executed as a script (not imported) +# This allows importing helper functions without triggering setup +if __name__ == "__main__" or "setuptools.build_meta" in sys.modules: + # Standard setup call + # For release builds using 'python -m build', libraries should be copied + # beforehand in the CI workflow + setup( + name=PACKAGE_NAME, + version=VERSION, + package_dir={"": "src"}, + packages=find_namespace_packages(where="src"), + include_package_data=True, + package_data={ + "c2pa": ["libs/*"], # Include all files in libs directory + }, + classifiers=[ + "Programming Language :: Python :: 3", + get_platform_classifier(get_current_platform()), + ], + python_requires=">=3.10", + long_description=open("README.md").read(), + long_description_content_type="text/markdown", + license="MIT OR Apache-2.0", + ) \ No newline at end of file