diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index 7301160..b50d1d9 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -9,7 +9,6 @@ on: jobs: deploy: - runs-on: ${{ matrix.os }} strategy: matrix: @@ -70,3 +69,34 @@ jobs: run: | python3 -m twine upload dist/* + deploySource: + needs: deploy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Display Python version + run: python3 -c "import sys; print(sys.version)" + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + pip3 install setuptools wheel twine + - name: Install APT On Linux + run: | + sudo apt-get update -qq -y + sudo apt-get install -qq -y libglu1-mesa build-essential libeigen3-dev + - name: Build + run: | + python3 setup.py sdist + + - name: Publish (Source) + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + twine upload dist/* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index afa8a84..f82d9e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,18 @@ All notable changes to this project will be documented in this file. ### Changed +## [0.1.7] - 2024-01-11 -## [0.1.6] - 2023-16-12 +### Added +- Updated build script to prepare source distribution (Linux) +- Script automatically pulls the specified submodule versions in setup.py + +### Fixed +- Fixed old references to original build-scripts +- Fixed the external submodules (clipper2, pybind, eigen) to fixed version for reference +- Fixed a build issue with latest ClipperLib (PreserveCollinear property has become a protected member) + +## [0.1.6] - 2023-12-16 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 3177394..a838f8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,7 +106,7 @@ link_directories( ) if(BUILD_PYTHON) - message(STATUS "Building PyCork Python Module") + message(STATUS "Building PyClipr Python Module") add_subdirectory(external/pybind11) @@ -202,40 +202,35 @@ else(BUILD_PYTHON) endif(BUILD_PYTHON) set(App_SRCS - cork/main.cpp + main.cpp ) SOURCE_GROUP("App" FILES ${App_SRCS}) if(BUILD_PYTHON) - set(PYCORK_SRCS + set(PYCLIPR_SRCS python/pyclipr/module.cpp ) - SOURCE_GROUP("Python" FILES ${PYCORK_SRCS}) + SOURCE_GROUP("Python" FILES ${PYCLIPR_SRCS}) - pybind11_add_module(pyclipr ${PYCORK_SRCS}) + pybind11_add_module(pyclipr ${PYCLIPR_SRCS}) #add_library(example MODULE main.cpp) - target_link_libraries(pyclipr PRIVATE pybind11::module clipr_static ${PYCORK_LIBS}) + target_link_libraries(pyclipr PRIVATE pybind11::module clipr_static ${PYCLIPR_LIBS}) set_target_properties(pyclipr PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" SUFFIX "${PYTHON_MODULE_EXTENSION}") - - #add_executable(main ${App_SRCS}) - - #target_link_libraries(main clipr_static ${PYCLIPR_LIBS}) - install(TARGETS pyclipr DESTINATION lib/pyclipr) else(BUILD_PYTHON) add_executable(main ${App_SRCS}) - target_link_libraries(main clipr ${PYCORK_LIBS}) + target_link_libraries(main clipr ${PYCLIPR_LIBS}) #install(TARGETS mpir DESTINATION ) diff --git a/MANIFEST.in b/MANIFEST.in index 50f7074..3369422 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,7 +2,7 @@ include LICENSE include README.rst include CHANGELOG.md include CMakeLists.txt -graft external/* -graft CMake/* -include python/pyclipr +recursive-include external * +include python/pyclipr/* + diff --git a/external/clipper2 b/external/clipper2 index 81b01d2..98db566 160000 --- a/external/clipper2 +++ b/external/clipper2 @@ -1 +1 @@ -Subproject commit 81b01d2acbad7b06fb28df4fbfbd7228519b7905 +Subproject commit 98db5662e8dd1808a5a7b50c5605a2289bb390e8 diff --git a/external/pybind11 b/external/pybind11 index 5ccb9e4..8a099e4 160000 --- a/external/pybind11 +++ b/external/pybind11 @@ -1 +1 @@ -Subproject commit 5ccb9e412d8974e8eeac1b061d9077ac0bd365e1 +Subproject commit 8a099e44b3d5f85b20f05828d919d2332a8de841 diff --git a/python/pyclipr/module.cpp b/python/pyclipr/module.cpp index 99b8944..2bdfeb5 100644 --- a/python/pyclipr/module.cpp +++ b/python/pyclipr/module.cpp @@ -576,12 +576,12 @@ PYBIND11_MODULE(pyclipr, m) { .def_readwrite("scaleFactor", &pyclipr::Clipper::scaleFactor, R"( Scale factor to be for transforming the input and output vectors. The default is 1000 )" ) - .def_readwrite("preserveCollinear", &pyclipr::Clipper::PreserveCollinear, R"( + .def_property("preserveCollinear", [](const pyclipr::Clipper &s ) { return s.PreserveCollinear();} + , [](pyclipr::Clipper &s, bool val ) { return s.PreserveCollinear(val);}, R"( By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before clipping. When enabled the PreserveCollinear property prevents this default behavior to allow these inner vertices to appear in the solution. )" ) - //.def("addPath", &pyclipr::Clipper::addPath) .def("addPath", &pyclipr::Clipper::addPath, py::arg("path"), py::arg("pathType"), py::arg("isOpen") = false, R"( The addPath method adds one or more closed subject paths (polygons) to the Clipper object. diff --git a/setup.py b/setup.py index d843c19..6df0157 100644 --- a/setup.py +++ b/setup.py @@ -8,10 +8,23 @@ from setuptools.command.build_ext import build_ext from distutils.version import LooseVersion +from setuptools.command.develop import develop +from setuptools.command.install import install +from setuptools.command.sdist import sdist +from setuptools.command.build_py import build_py +from setuptools import setup, find_packages +from subprocess import check_call, check_output with open('README.rst') as f: readme = f.read() +""" Specific versions of submodules to use. """ + +submoduleVersions = { + 'clipper2': 'Clipper2_1.3.0', + 'pybind11': 'v2.11', + 'eigen': '3.4' +} class CMakeExtension(Extension): def __init__(self, name, modName, sourcedir=''): @@ -22,8 +35,67 @@ def __init__(self, name, modName, sourcedir=''): self.sourcedir = os.path.abspath(sourcedir) +def gitcmd_update_submodules(): + """ + Check if the package is being deployed as a git repository. If so, recursively update all dependencies. + """ + + if os.path.exists('.git'): + + check_call(['git', 'submodule', 'update', '--init', '--recursive']) + + # set all versions as required + curPath = os.path.abspath('.') + + for k, v in submoduleVersions.items(): + modPath = os.path.abspath('{:s}/external/{:s}'.format(curPath, k)) + + import subprocess + + process = subprocess.Popen(['git', 'checkout', v], cwd=modPath) + + + check_call(['git', 'submodule', 'status']) + + return True + + return False + + +class gitcmd_develop(develop): + """ + Specialized packaging class that runs `git submodule update --init --recursive` + as part of the update/install procedure. + """ + def run(self): + gitcmd_update_submodules() + develop.run(self) + + +class gitcmd_install(install): + """ + Specialized packaging class that runs `git submodule update --init --recursive` + as part of the update/install procedure. + """ + def run(self): + gitcmd_update_submodules() + install.run(self) + +class gitcmd_sdist(sdist): + """ + Specialized packaging class that runs git submodule update --init --recursive + as part of the update/install procedure;. + """ + def run(self): + gitcmd_update_submodules() + sdist.run(self) + class CMakeBuild(build_ext): def run(self): + + # Update the submodules to the correct version + gitcmd_update_submodules() + try: out = subprocess.check_output(['cmake', '--version']) except OSError: @@ -39,6 +111,11 @@ def run(self): self.build_extension(ext) def build_extension(self, ext): + """ + Builds the following CMake extension within the project tree + + :param ext: CMake Extension to build + """ print('ext_full_path', self.get_ext_fullpath(ext.name)) extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) # required for auto-detection of auxiliary "native" libs @@ -71,12 +148,10 @@ def build_extension(self, ext): subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env) subprocess.check_call(['cmake', '--build', '.', '--target', ext.modName] + build_args, cwd=self.build_temp) - # subprocess.check_call(['cmake', '--build', '.', '--target', 'install'], cwd=self.build_temp) - setup( name='pyclipr', - version='0.1.6', + version='0.1.7', author='Luke Parry', author_email='dev@lukeparry.uk', url='https://github.com/drlukeparry/pyclipr', @@ -84,7 +159,11 @@ def build_extension(self, ext): long_description_content_type = 'text/x-rst', description='Python library for polygon clipping and offsetting based on Clipper2.', ext_modules=[CMakeExtension('pyclipr.pyclipr', 'pyclipr')], - cmdclass=dict(build_ext=CMakeBuild), + cmdclass= { + 'build_ext': CMakeBuild, + 'develop': gitcmd_develop, + 'sdist': gitcmd_sdist, + }, packages = ['pyclipr'], package_dir={'': 'python'}, keywords=['polygon clipping', 'polygon offsetting', 'libClipper', 'Clipper2', 'polygon boolean', 'polygon', 'line clipping', 'clipper'],