GitHub Action을 사용하여 Dynamsoft C++ Barcode SDK용 Python 휠 패키지 빌드

21589 단어
C 또는 C++에서 Python 확장을 구현하는 것은 쉽지만 다른 운영 체제 및 다른 Python 버전에 대한 Python 휠 패키지에 기본 모듈을 빌드하는 것은 악몽입니다. CPython 휠 패키지는 Python 버전에 따라 다르므로 CPython 모듈이 Python 3.x에서 보편적으로 작동하도록 하려면 운영 체제별로 Python 3.6, Python 3.7, Python 3.8, Python 3.9 및 Python 3.10용 휠을 빌드해야 합니다. . 최대 패키지 수는 Python versions (3.6, 3.7, 3.8, 3.9, 3.10) * operating systems (Windows, Linux, macOS) * CPU architectures (x64, aarch64) 입니다. 프로세스를 단순화하기 위해 GitHub Actions를 활용할 수 있습니다. 이 기사에서는 Dynamsoft C/C++ Barcode SDK를 예로 들어 설명합니다. 외부 C/C++ 라이브러리( *.dll, *.so, *.dylib )에 연결되는 CPython 확장을 빌드하는 방법과 GitHub Actions를 사용하여 Python 휠 패키지를 빌드 및 게시하는 프로세스를 자동화하는 방법을 볼 수 있습니다.

요구 사항



Dynamsoft C/C++ Barcode SDK v9.0

Scikit-build로 CPython 확장 프로젝트 빌드



Python 개발 가이드를 읽었다면 distutils.core.Extension이 가장 널리 사용되는 Python 확장 빌더라는 것을 알 수 있습니다. 그러나 distutils는 휠 패키지 생성을 위한 pip wheel 명령을 실행할 때 확장을 순차적으로 빌드하고 생성된 라이브러리를 패키지 폴더로 패키징할 수 없습니다.

Scikit-builddistutils의 대안입니다. CMake 빌드로 기능을 확장합니다distutils. scikit-build를 시작하려면 scikit-build-sample-projects을 방문하십시오.

Python 바코드 및 QR 코드 확장 프로젝트의 경우 setup.py 파일은 다음과 같습니다.

from skbuild import setup
import io

packages = ['barcodeQrSDK']

setup (name = 'barcode-qr-code-sdk',
            version = '9.0.3',
            description = 'Barcode and QR code scanning SDK for Python',
            packages=packages,
            include_package_data=False,
          )


보시다시피 setup.py 파일은 setup.py 와 함께 사용되는 disutils 파일에 비해 매우 간단합니다. 패키지 폴더만 포함합니다. 확장 빌드를 트리거하기 위해 CMakeLists.txt 파일과 함께 setup.py를 생성합니다.

cmake_minimum_required(VERSION 3.4...3.22)

project(barcodeQrSDK)

find_package(PythonExtensions REQUIRED)

if(CMAKE_HOST_UNIX)
    if(CMAKE_HOST_APPLE)
        SET(CMAKE_CXX_FLAGS "-std=c++11 -O3 -Wl,-rpath,@loader_path")
        SET(CMAKE_INSTALL_RPATH "@loader_path")
    else()
        SET(CMAKE_CXX_FLAGS "-std=c++11 -O3 -Wl,-rpath=$ORIGIN")
        SET(CMAKE_INSTALL_RPATH "$ORIGIN")
    endif()
    SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()

MESSAGE( STATUS "CPU architecture ${CMAKE_SYSTEM_PROCESSOR}" )
if(CMAKE_HOST_WIN32)
    link_directories("${PROJECT_SOURCE_DIR}/lib/win/") 
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
        MESSAGE( STATUS "Link directory: ${PROJECT_SOURCE_DIR}/lib/linux/" )
        link_directories("${PROJECT_SOURCE_DIR}/lib/linux/")
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
        MESSAGE( STATUS "Link directory: ${PROJECT_SOURCE_DIR}/lib/arm32/" )
        link_directories("${PROJECT_SOURCE_DIR}/lib/arm32/") 
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) 
        MESSAGE( STATUS "Link directory: ${PROJECT_SOURCE_DIR}/lib/aarch64/" )
        link_directories("${PROJECT_SOURCE_DIR}/lib/aarch64/") 
    endif()
elseif(CMAKE_HOST_APPLE)
    MESSAGE( STATUS "Link directory: ${PROJECT_SOURCE_DIR}/lib/macos/" )
    link_directories("${PROJECT_SOURCE_DIR}/lib/macos/") 
endif()
include_directories("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/include/")

add_library(${PROJECT_NAME} MODULE src/barcodeQrSDK.cpp)
if(CMAKE_HOST_WIN32)
    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        target_link_libraries (${PROJECT_NAME} "DynamsoftBarcodeReaderx64")
    else()
        target_link_libraries (${PROJECT_NAME} "DBRx64")
    endif()
else()
    target_link_libraries (${PROJECT_NAME} "DynamsoftBarcodeReader" pthread)
endif()

if(CMAKE_HOST_WIN32)
    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E copy_directory
    "${PROJECT_SOURCE_DIR}/lib/win/"      
    $<TARGET_FILE_DIR:${PROJECT_NAME}>)
endif()

python_extension_module(barcodeQrSDK)
install(TARGETS barcodeQrSDK LIBRARY DESTINATION barcodeQrSDK)

if(CMAKE_HOST_WIN32)
    install (DIRECTORY  "${PROJECT_SOURCE_DIR}/lib/win/" DESTINATION barcodeQrSDK)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
        install (DIRECTORY  "${PROJECT_SOURCE_DIR}/lib/linux/" DESTINATION barcodeQrSDK)
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR ARM32_BUILD)
        install (DIRECTORY  "${PROJECT_SOURCE_DIR}/lib/arm32/" DESTINATION barcodeQrSDK)
    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) 
        install (DIRECTORY  "${PROJECT_SOURCE_DIR}/lib/aarch64/" DESTINATION barcodeQrSDK)
    endif()
elseif(CMAKE_HOST_APPLE)
    install (DIRECTORY  "${PROJECT_SOURCE_DIR}/lib/macos/" DESTINATION barcodeQrSDK)
endif()

CMakeLists.txt 파일에서 수행하는 작업:
  • 빌드 인수를 설정합니다. rpath는 Linux 및 macOS에서 종속 공유 라이브러리를 찾는 데 중요합니다.
  • 헤더 파일 및 라이브러리의 디렉토리를 설정합니다.
  • 확장 모듈을 빌드합니다.
  • 외부 동적 라이브러리를 연결합니다.
  • Python 모듈 및 종속 라이브러리를 barcodeQrSDK 패키지 폴더에 복사합니다.
  • __init__.py 패키지 폴더에도 barcodeQrSDK 파일이 필요합니다.

    from .barcodeQrSDK import * 
    __version__ = version
    

    python setup.py develop 명령을 실행하여 확장 모듈을 테스트하십시오. 오류가 없으면 휠 패키지를 만들 수 있습니다.

    pip wheel .
    


    휠 패키지가 성공적으로 빌드되면 폴더 구조는 다음과 같습니다.





    GitHub 작업으로 여러 휠 패키지 만들기



    위에서 언급했듯이 Python의 각 버전과 다른 플랫폼에 대해 여러 휠 패키지를 만드는 것은 우리를 미치게 만듭니다. 다행스럽게도 GitHub Actions는 많은 작업을 덜어줄 수 있습니다.

    다음은 여러 휠 패키지를 빌드하고 게시하는 단계입니다.
  • 저장소 홈페이지로 이동하고 Actions를 클릭하여 새 작업 흐름을 만듭니다.
  • set up a workflow yourself를 클릭하여 사용자 정의 워크플로를 생성합니다. cibuildwheel에서 제공하는 예를 참조할 수 있습니다.

    name: Build and upload to PyPI
    
    on: [push, pull_request]
    
    jobs:
    build_wheels:
        name: Build wheels on ${{ matrix.os }}
        runs-on: ${{ matrix.os }}
        strategy:
        matrix:
            os: [windows-2019, macos-10.15]
    
        steps:
        - uses: actions/checkout@v2
    
        - name: Build wheels
            uses: pypa/[email protected]
            env:
            CIBW_ARCHS_WINDOWS: AMD64
            CIBW_ARCHS_MACOS: x86_64
            CIBW_ARCHS_LINUX: "x86_64 aarch64"
            CIBW_SKIP: "pp* *-win32 *-manylinux_i686"
    
        - uses: actions/upload-artifact@v2
            with:
            path: ./wheelhouse/*.whl
    
    build_sdist:
        name: Build source distribution
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v2
    
        - name: Build sdist
            run: pipx run build --sdist
    
        - uses: actions/upload-artifact@v2
            with:
            path: dist/*.tar.gz
    
    upload_pypi:
        needs: [build_wheels, build_sdist]
        runs-on: ubuntu-latest
        # upload to PyPI on every tag starting with 'v'
        if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
        # alternatively, to publish when a GitHub Release is created, use the following rule:
        # if: github.event_name == 'release' && github.event.action == 'published'
        steps:
        - uses: actions/download-artifact@v2
            with:
            name: artifact
            path: dist
    
        - uses: pypa/[email protected]
            with:
            user: __token__
            password: ${{ secrets.pypi_password }}
            skip_existing: true
    

    우리의 확장은 64비트 전용이므로 CIBW_SKIP: "pp* *-win32 *-manylinux_i686"를 설정하여 32비트 빌드를 건너뛸 수 있습니다. OS 아키텍처를 지정할 수도 있습니다.

    CIBW_ARCHS_WINDOWS: AMD64
    CIBW_ARCHS_MACOS: x86_64
    CIBW_ARCHS_LINUX: "x86_64 aarch64"
    

  • Settings > Secrets > Actions로 이동하여 휠 패키지를 pypi.org에 게시하기 위한 저장소 암호를 생성합니다.



  • 워크플로를 완료한 후 생성 휠 패키지가 포함된 아티팩트를 다운로드할 수 있습니다.



    게다가 휠 패키지는 pypi.org에서 다운로드할 수 있습니다.



  • 소스 코드



    https://github.com/yushulx/python-barcode-qrcode-sdk

    좋은 웹페이지 즐겨찾기