diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f6f964c..224ee7d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,7 @@ on: env: BUILD_CONFIGURATION: Release BUILD_DIR: _build + POSELIB_VERSION: a69263d5d8 jobs: build: @@ -22,10 +23,15 @@ jobs: fail-fast: false matrix: config: - - { name: Linux, os: ubuntu-latest, artifact: 'libHomLib-linux.zip' } - - env: - POSELIB_VERSION: "v2.0.5" + - name: Linux + os: ubuntu-latest + artifact: 'libHomLib-linux.zip' + - name: macOS + os: macos-latest + artifact: 'libHomLib-macos.zip' + - name: Windows + os: windows-latest + artifact: 'libHomLib-windows.zip' steps: - name: Checkout your project @@ -44,6 +50,13 @@ jobs: run: | brew install cmake eigen + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + run: | + vcpkg install eigen3:x64-windows + env: + VCPKG_ROOT: C:\vcpkg + - name: Cache PoseLib build uses: actions/cache@v4 id: cache-poselib @@ -54,36 +67,124 @@ jobs: - name: Build and install PoseLib if: steps.cache-poselib.outputs.cache-hit != 'true' run: | - git clone --branch ${{ env.POSELIB_VERSION }} https://github.com/PoseLib/PoseLib.git + git clone https://github.com/PoseLib/PoseLib.git cd PoseLib + git checkout ${{ env.POSELIB_VERSION }} mkdir build && cd build - cmake .. -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/poselib-install \ - -DPOSELIB_BUILD_TESTS=OFF \ - -DPOSELIB_BUILD_EXAMPLES=OFF - make -j$(nproc) - make install + cmake_args="-DCMAKE_INSTALL_PREFIX=${{github.workspace}}/poselib-install \ + -DPOSELIB_BUILD_TESTS=OFF \ + -DPOSELIB_BUILD_EXAMPLES=OFF" + if [[ "$RUNNER_OS" == "Windows" ]]; then + cmake_args="$cmake_args -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake" + fi + cmake .. $cmake_args + cmake --build . --config ${{env.BUILD_CONFIGURATION}} --parallel + cmake --install . --config ${{env.BUILD_CONFIGURATION}} + shell: bash - name: Configure project run: | - cmake \ - -B ${{github.workspace}}/${{env.BUILD_DIR}} \ - -DCMAKE_PREFIX_PATH=${{github.workspace}}/poselib-install \ - -DCMAKE_BUILD_TYPE=${{env.BUILD_CONFIGURATION}} \ + cmake_args="-B ${{github.workspace}}/${{env.BUILD_DIR}} \ + -DCMAKE_PREFIX_PATH=${{github.workspace}}/poselib-install \ + -DCMAKE_BUILD_TYPE=${{env.BUILD_CONFIGURATION}}" + if [[ "$RUNNER_OS" == "Windows" ]]; then + cmake_args="$cmake_args -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" + fi + cmake $cmake_args + shell: bash + - name: Compile and Install run: | - cmake \ - --build ${{github.workspace}}/${{env.BUILD_DIR}} \ - --config ${{env.BUILD_CONFIGURATION}} \ - -j $(nproc) + if [[ "$RUNNER_OS" == "Windows" ]]; then + build_path="${{github.workspace}}\\${{env.BUILD_DIR}}" + else + build_path="${{github.workspace}}/${{env.BUILD_DIR}}" + fi + cmake --build "$build_path" --config ${{env.BUILD_CONFIGURATION}} --parallel + shell: bash - name: Execute Tests - run: ctest --test-dir ${{github.workspace}}/${{env.BUILD_DIR}}/tests -j $(nproc) --output-on-failure + run: | + if [[ "$RUNNER_OS" == "Windows" ]]; then + test_path="${{github.workspace}}\\${{env.BUILD_DIR}}\\tests" + else + test_path="${{github.workspace}}/${{env.BUILD_DIR}}/tests" + fi + ctest --test-dir "$test_path" --output-on-failure + shell: bash + + - name: Execute Example + shell: bash + run: | + if [[ "$RUNNER_OS" == "Windows" ]]; then + "${{github.workspace}}\\${{env.BUILD_DIR}}\\examples\\${{env.BUILD_CONFIGURATION}}\\example.exe" + else + "${{github.workspace}}/${{env.BUILD_DIR}}/examples/example" + fi + + - name: Execute RANSAC Example + shell: bash + run: | + if [[ "$RUNNER_OS" == "Windows" ]]; then + "${{github.workspace}}\\${{env.BUILD_DIR}}\\examples\\${{env.BUILD_CONFIGURATION}}\\example_ransac.exe" + else + "${{github.workspace}}/${{env.BUILD_DIR}}/examples/example_ransac" + fi - - name: Execute Examples - run: ${{github.workspace}}/${{env.BUILD_DIR}}/examples/example + build_python: + name: Build Python for ${{ matrix.config.name }} + needs: [build] + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - name: Linux + os: ubuntu-latest + artifact: 'libHomLib-linux.zip' + - name: macOS + os: macos-latest + artifact: 'libHomLib-macos.zip' + - name: Windows + os: windows-latest + artifact: 'libHomLib-windows.zip' + + steps: + - name: Checkout your project + uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential libeigen3-dev + + - name: Install dependencies (macOS) + if: runner.os == 'macOS' + run: | + brew install cmake eigen + + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + run: | + vcpkg install eigen3:x64-windows + env: + VCPKG_ROOT: C:\vcpkg + + - name: Restore PoseLib cache + uses: actions/cache@v4 + id: cache-poselib + with: + path: ${{github.workspace}}/poselib-install + key: ${{ runner.os }}-poselib-${{ env.POSELIB_VERSION }} - - name: Execute RANSAC Examples - run: ${{github.workspace}}/${{env.BUILD_DIR}}/examples/example_ransac + - name: Fail if cache miss + if: steps.cache-poselib.outputs.cache-hit != 'true' + run: | + echo "Cache miss for PoseLib. Build cannot proceed." + exit 1 - name: Setup python uses: actions/setup-python@v5 @@ -93,21 +194,143 @@ jobs: - name: Build python package run: | python -m pip install build - python -m build --config-setting=cmake.args="-DCMAKE_PREFIX_PATH=${{github.workspace}}/poselib-install" - - - name: Install and test python pacakge + if [[ "$RUNNER_OS" == "Windows" ]]; then + python -m build --config-setting=cmake.args="-DCMAKE_PREFIX_PATH=${{github.workspace}}\\poselib-install" + else + python -m build --config-setting=cmake.args="-DCMAKE_PREFIX_PATH=${{github.workspace}}/poselib-install" + fi + shell: bash + + - name: Install and test python package run: | + wheel_file=$(ls dist/*.whl 2>/dev/null | head -n1) + if [ -n "$wheel_file" ]; then + echo "Found wheel: $wheel_file" + else + echo "Did not find wheel in dist. Exiting.." + exit 1 + fi python -m pip install pytest pytest-approvaltests numpy - python -m pip install dist/*.whl + python -m pip install "$wheel_file" python -m pytest -s python/tests - - - name: Package artifacts shell: bash + + build_wheels: + name: Build wheels for ${{ matrix.config.name }} + needs: [build, build_python] + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - name: linux-intel + os: ubuntu-latest + - name: macos + os: macos-latest + - name: windows + os: windows-latest + + steps: + - name: Checkout your project + uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Restore PoseLib cache + uses: actions/cache@v4 + id: cache-poselib + with: + path: ${{github.workspace}}/poselib-install + key: ${{ runner.os }}-poselib-${{ env.POSELIB_VERSION }} + + - name: Fail if cache miss + if: steps.cache-poselib.outputs.cache-hit != 'true' run: | - zip -r ${{ matrix.config.artifact }} ${{github.workspace}}/${{env.BUILD_DIR}} + echo "Cache miss for PoseLib. Build cannot proceed." + exit 1 + + - name: Build wheels + uses: pypa/cibuildwheel@v3.3.1 + env: + CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10" + CIBW_BUILD: ${{ github.event_name == 'pull_request' && 'cp310-*' || '' }} + CIBW_BEFORE_ALL_LINUX: yum install -y eigen3-devel + CIBW_ENVIRONMENT_LINUX: BUILD_SHARED_LIBS="OFF" CMAKE_PREFIX_PATH="/project/poselib-install" + CIBW_ARCHS_LINUX: "native" + CIBW_BEFORE_ALL_WINDOWS: > + C:\vcpkg\vcpkg --triplet x64-windows install eigen3 && + if not exist D:\poselib mkdir D:\poselib && + xcopy /E /I "%GITHUB_WORKSPACE%\poselib-install\*" D:\poselib\ + CIBW_ENVIRONMENT_WINDOWS: BUILD_SHARED_LIBS="OFF" CMAKE_PREFIX_PATH="D:\\poselib" CMAKE_TOOLCHAIN_FILE="C:\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake" + CIBW_ARCHS_WINDOWS: "native" + CIBW_BEFORE_ALL_MACOS: brew install eigen + CIBW_ENVIRONMENT_MACOS: BUILD_SHARED_LIBS="OFF" CMAKE_PREFIX_PATH="$GITHUB_WORKSPACE/poselib-install" + CIBW_REPAIR_WHEEL_COMMAND_MACOS: "" + CIBW_SKIP: "*-musllinux_x86_64" + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.config.name }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + + build_sdist: + name: Build source distribution + needs: [build] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Build sdist + run: pipx run build --sdist - - name: Upload artifact (for later release) - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v4 with: - name: ${{ matrix.config.artifact }} - path: ${{ matrix.config.artifact }} + name: cibw-sdist + path: ./dist/*.tar.gz + + release: + name: Create GitHub Release + needs: [build, build_wheels, build_sdist] + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Display structure of downloaded files + run: ls -R artifacts + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + name: Release ${{ github.ref_name }} + tag_name: ${{ github.ref_name }} + body: | + ## Changes + See the commits for details. + draft: false + prerelease: false + files: libHomLib-*.zip + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + upload_pypi: + runs-on: ubuntu-latest + needs: [build, build_wheels, build_sdist] + environment: pypi publisher + permissions: + id-token: write + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/download-artifact@v5 + with: + pattern: cibw-* + path: dist + merge-multiple: true + + - uses: pypa/gh-action-pypi-publish@release/v1 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index dc87517..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Release - -on: - workflow_run: - workflows: ["Build Wheels"] - types: - - completed - branches: - - main - tags: - - 'v*' - -jobs: - release: - name: Create GitHub Release - if: ${{ github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_ref, 'refs/tags/v') }} - permissions: - id-token: write - runs-on: ubuntu-latest - steps: - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - run-id: ${{ github.event.workflow_run.id }} - path: artifacts - merge-multiple: true - - - name: Display structure of downloaded files - run: ls -R artifacts - - - name: Create Release - uses: softprops/action-gh-release@v2 - with: - name: Release ${{ github.ref_name }} - tag_name: ${{ github.ref_name }} - body: | - ## Changes - - See the commits for details. - draft: false - prerelease: false - files: artifacts/*.zip - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - upload_pypi: - name: Upload PyPI - runs-on: ubuntu-latest - environment: pypi publisher - permissions: - id-token: write - if: ${{ github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_ref, 'refs/tags/v') }} - steps: - - uses: actions/download-artifact@v5 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - run-id: ${{ github.event.workflow_run.id }} - # unpacks all CIBW artifacts into dist/ - pattern: cibw-* - path: dist - merge-multiple: true - - - uses: pypa/gh-action-pypi-publish@release/v1 - # To test uploads to TestPyPI, uncomment the following: - # with: - # repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml deleted file mode 100644 index 3684502..0000000 --- a/.github/workflows/wheels.yml +++ /dev/null @@ -1,109 +0,0 @@ -name: Build Wheels - -on: - workflow_run: - workflows: ["Build HomLib"] - types: - - completed - branches: - - main - tags: - - 'v*' - -jobs: - build_wheels: - if: ${{ github.event.workflow_run.conclusion == 'success' }} - name: Build wheels for ${{ matrix.config.name }} - runs-on: ${{ matrix.config.os }} - strategy: - fail-fast: false - matrix: - config: - - name: linux-intel - os: ubuntu-latest - env: - POSELIB_VERSION: "v2.0.5" - - steps: - - name: Checkout your project - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: Restore PoseLib cache - uses: actions/cache@v4 - id: cache-poselib - with: - path: ${{github.workspace}}/poselib-install - key: ${{ runner.os }}-poselib-${{ env.POSELIB_VERSION }} - - - name: Fail if cache miss - if: steps.cache-poselib.outputs.cache-hit != 'true' - run: | - echo "Cache miss for PoseLib. Build cannot proceed." - exit 1 - - - name: Build wheels - uses: pypa/cibuildwheel@v3.3.1 - env: - CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10" - CIBW_ENVIRONMENT: | - BUILD_SHARED_LIBS="OFF" - CMAKE_CXX_FLAGS="-Wno-error" - CIBW_BUILD: ${{ github.event_name == 'pull_request' && 'cp310-*' || '' }} - CIBW_BEFORE_ALL_LINUX: | - yum install -y eigen3-devel - cp -r /project/poselib-install/* /usr/local/ - CIBW_ARCHS_LINUX: "native" - CIBW_BEFORE_ALL_WINDOWS: C:\vcpkg\vcpkg --triplet x64-windows install eigen3 - CIBW_ENVIRONMENT_WINDOWS: CMAKE_TOOLCHAIN_FILE="C:\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake" - CIBW_ARCHS_WINDOWS: "native" - CIBW_BEFORE_ALL_MACOS: brew install eigen - CIBW_REPAIR_WHEEL_COMMAND_MACOS: "" - CIBW_SKIP: "*-musllinux_x86_64" - - - uses: actions/upload-artifact@v4 - with: - name: cibw-wheels-${{ matrix.config.name }}-${{ strategy.job-index }} - path: ./wheelhouse/*.whl - - build_sdist: - name: Build source distribution - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Build sdist - run: pipx run build --sdist - - - uses: actions/upload-artifact@v4 - with: - name: cibw-sdist - path: ./dist/*.tar.gz - - combine_artifacts: - needs: [build_wheels, build_sdist] - runs-on: ubuntu-latest - steps: - - name: Download wheels from this workflow - uses: actions/download-artifact@v4 - with: - path: downloaded - merge-multiple: true - - name: Download library artifacts from main.yml - uses: actions/download-artifact@v4 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - run-id: ${{ github.event.workflow_run.id }} - path: library - - name: Combine and upload - run: | - mkdir combined - cp -r library/* combined/ || true - cp -r downloaded/* combined/ || true - - uses: actions/upload-artifact@v4 - with: - name: combined-release-artifacts - path: combined/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2154796..88705bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,41 @@ cmake_minimum_required(VERSION 3.15) -project(HomLib) +# ---------------------------------------------------------------------- +# Extract version from pyproject.toml +# ---------------------------------------------------------------------- +file(READ "${CMAKE_CURRENT_SOURCE_DIR}/pyproject.toml" PYPROJECT_CONTENT) +string(REGEX MATCH "version[ \t]*=[ \t]*[\"']([^\"']+)[\"']" _ ${PYPROJECT_CONTENT}) +set(PROJECT_VERSION_FULL ${CMAKE_MATCH_1}) + +if(NOT PROJECT_VERSION_FULL) + message(FATAL_ERROR "Version not found in pyproject.toml") +endif() + +message(STATUS "Project version: ${PROJECT_VERSION_FULL}") + +# ---------------------------------------------------------------------- +# Extract numeric version for CMake +# ---------------------------------------------------------------------- +# Look for the pattern "major.minor.patch" at the beginning +string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" _ "${PROJECT_VERSION_FULL}") +if(CMAKE_MATCH_1) + set(VERSION_MAJOR ${CMAKE_MATCH_1}) + set(VERSION_MINOR ${CMAKE_MATCH_2}) + set(VERSION_PATCH ${CMAKE_MATCH_3}) + set(PROJECT_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +else() + # Fallback if no numeric parts found + set(PROJECT_VERSION "0.0.0") +endif() + +project(HomLib VERSION ${PROJECT_VERSION} LANGUAGES CXX) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() if(CMAKE_COMPILER_IS_GNUCXX) - message("USING GNUCXX compiler") + message(STATUS "USING GNUCXX compiler") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-strict-aliasing") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wno-write-strings") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -ansi") diff --git a/HomLib/solvers/kukelova_cvpr_2015/get_kukelova_cvpr_2015.cpp b/HomLib/solvers/kukelova_cvpr_2015/get_kukelova_cvpr_2015.cpp index a0d2a3e..b63e45d 100644 --- a/HomLib/solvers/kukelova_cvpr_2015/get_kukelova_cvpr_2015.cpp +++ b/HomLib/solvers/kukelova_cvpr_2015/get_kukelova_cvpr_2015.cpp @@ -20,6 +20,7 @@ #include "get_kukelova_cvpr_2015.hpp" #include +#include #include #include "solver_kukelova_cvpr_2015.hpp" #include "normalize2dpts.hpp" diff --git a/README.md b/README.md index f5289dd..66173c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # HomLib ![GitHub release (latest by date)](https://img.shields.io/github/v/release/marcusvaltonen/HomLib) ![GitHub](https://img.shields.io/github/license/marcusvaltonen/HomLib) +![PyPI](https://img.shields.io/pypi/v/homlib) + C++ library for computing homographies with support in MATLAB and Python. @@ -108,10 +110,6 @@ Note: Solvers with known IMU data is not yet supported in the python package. $ pip install homlib ``` -(BELOW IS DEPREACATED) -The official python repository is [python-homlib](https://github.com/marcusvaltonen/python-homlib). -A pre-alpha release is available at PyPi, and can be installed using - ## About the solvers Many of the solvers were generated using the automatic generator proposed by Larsson et al. "Efficient Solvers for Minimal Problems by Syzygy-based diff --git a/pyproject.toml b/pyproject.toml index 08b7045..29a1e2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "homlib" -version = "0.1.1-rc5" +version = "0.1.1-rc7" description = "State-of-the-art homography estimators." readme = "README.md" authors = [ diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index c32f6f5..06e0a8b 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -7,9 +7,16 @@ cmake_minimum_required(VERSION 3.15...3.27) project( ${SKBUILD_PROJECT_NAME} VERSION ${SKBUILD_PROJECT_VERSION} - LANGUAGES CXX) + LANGUAGES CXX +) -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ftree-vectorize -funroll-loops") +if(MSVC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") +else() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ftree-vectorize -funroll-loops") +endif() + +message(STATUS "CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") # Find the module development requirements (requires FindPython from 3.17 or # scikit-build-core's built-in backport) @@ -33,6 +40,9 @@ target_link_libraries(_core PRIVATE HomLib) target_link_libraries(_core PRIVATE PoseLib::PoseLib) target_include_directories(_core PRIVATE ${HOMLIB_INCLUDE_DIRS}) target_include_directories(_core PRIVATE ../thirdparty/RansacLib) - +target_compile_definitions(_core PRIVATE HOMLIB_VERSION="${PROJECT_VERSION_FULL}") +if(MSVC) + target_compile_definitions(_core PRIVATE _USE_MATH_DEFINES) +endif() # The install directory is the output (wheel) directory install(TARGETS _core DESTINATION homlib) diff --git a/python/src/homlib/__init__.py b/python/src/homlib/__init__.py index 8a93f84..a21b2a0 100644 --- a/python/src/homlib/__init__.py +++ b/python/src/homlib/__init__.py @@ -2,6 +2,7 @@ from ._core import ( __doc__, + __version__, PoseData, estimate_fitzgibbon_cvpr_2001_one_sided, estimate_fitzgibbon_cvpr_2001_two_sided_equal, @@ -24,7 +25,6 @@ LORansacOptions, RansacStatistics, ) -from .version import __version__ __all__ = [ "__doc__", diff --git a/python/src/homlib/version.py b/python/src/homlib/version.py deleted file mode 100644 index 5729925..0000000 --- a/python/src/homlib/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.1-rc5" diff --git a/python/src/main.cpp b/python/src/main.cpp index aedf7e2..a9e2317 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -285,6 +285,12 @@ PYBIND11_MODULE(_core, m) { RansacStatistics )pbdoc"; + + #ifdef HOMLIB_VERSION + m.attr("__version__") = py::str(HOMLIB_VERSION); + #else + m.attr("__version__") = py::str("dev"); + #endif py::class_(m, "PoseData") .def(