diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec58a06..8b3d198 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,35 +1,29 @@ -name: build - -on: +name: build +on: push: - branches: + branches: - master pull_request: branches: - master - jobs: - build-debug: name: CMake Debug Build - runs-on: ubuntu-20.04 - + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: install-eigen + - uses: actions/checkout@v4 + - name: install-dependencies run: sudo apt install libeigen3-dev - name: configure run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. - name: build run: cmake --build build - build-release: name: CMake Release Build - runs-on: ubuntu-20.04 - + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: install-eigen + - uses: actions/checkout@v4 + - name: install-dependencies run: sudo apt install libeigen3-dev - name: configure run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. @@ -37,4 +31,19 @@ jobs: run: cmake --build build - name: test run: cd build && ctest all - + python: + name: Python Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: setup-python + uses: actions/setup-python@v5 + with: {python-version: '3.x'} + - name: install-dependencies + run: sudo apt install libeigen3-dev + - name: upgrade-pip + run: python -m pip install --upgrade pip + - name: build + run: python -m pip install ${{github.workspace}} + - name: test + run: python -c "import teaserpp_python; print('☺')" diff --git a/CMakeLists.txt b/CMakeLists.txt index a7fd037..be1e677 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.16) project(teaserpp VERSION 1.0.0) set(CMAKE_CXX_STANDARD 14) @@ -18,10 +18,11 @@ if (DEFINED SKBUILD) endif () # Options +option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(BUILD_TESTS "Build tests" ON) option(BUILD_TEASER_FPFH "Build TEASER++ wrappers for PCL FPFH estimation." OFF) option(BUILD_MATLAB_BINDINGS "Build MATLAB bindings" OFF) -option(BUILD_PYTHON_BINDINGS "Build Python bindings" ON) +option(BUILD_PYTHON_BINDINGS "Build Python bindings" OFF) option(BUILD_DOC "Build documentation" ON) option(BUILD_WITH_MARCH_NATIVE "Build with flag march=native" OFF) option(ENABLE_MKL "Try to use Eigen with MKL" OFF) @@ -32,11 +33,6 @@ if (ENABLE_DIAGNOSTIC_PRINT) add_definitions(-DTEASER_DIAG_PRINT) endif () -# Cache Variables -if (NOT TEASERPP_PYTHON_VERSION) - set(TEASERPP_PYTHON_VERSION "" CACHE STRING "Python version to use for TEASER++ bindings.") -endif () - # Find dependencies # Eigen3 find_package(Eigen3 3.2 QUIET REQUIRED NO_MODULE) @@ -78,44 +74,6 @@ if (BUILD_TEASER_FPFH) endif() endif () -# googletest -configure_file(cmake/GoogleTest.CMakeLists.txt.in googletest-download/CMakeLists.txt) -execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download") -execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download") -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -add_subdirectory("${CMAKE_BINARY_DIR}/googletest-src" - "${CMAKE_BINARY_DIR}/googletest-build" EXCLUDE_FROM_ALL) - -# pmc (Parallel Maximum Clique) -configure_file(cmake/pmc.CMakeLists.txt.in pmc-download/CMakeLists.txt) -execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/pmc-download") -execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/pmc-download") -add_subdirectory("${CMAKE_BINARY_DIR}/pmc-src" - "${CMAKE_BINARY_DIR}/pmc-build") - -# tinyply -configure_file(cmake/tinyply.CMakeLists.txt.in tinyply-download/CMakeLists.txt) -execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tinyply-download") -execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tinyply-download") -add_subdirectory("${CMAKE_BINARY_DIR}/tinyply-src" - "${CMAKE_BINARY_DIR}/tinyply-build") -target_include_directories(tinyply PUBLIC - $) - -# spectra -configure_file(cmake/spectra.CMakeLists.txt.in spectra-download/CMakeLists.txt) -execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/spectra-download") -execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/spectra-download") -set(SPECTRA_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/spectra-src/include") - # Building Targets set(TEASERPP_ROOT ${CMAKE_CURRENT_LIST_DIR}) add_subdirectory(teaser) @@ -135,17 +93,6 @@ if (BUILD_MATLAB_BINDINGS) endif () if (BUILD_PYTHON_BINDINGS) - set(PYBIND11_PYTHON_VERSION ${TEASERPP_PYTHON_VERSION}) - - # download the pybind11 repo - configure_file(cmake/pybind11.CMakeLists.txt.in pybind11-download/CMakeLists.txt) - execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/pybind11-download") - execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/pybind11-download") - add_subdirectory("${CMAKE_BINARY_DIR}/pybind11-src" - "${CMAKE_BINARY_DIR}/pybind11-build") - message(STATUS "TEASER++ Python binding will be built.") add_subdirectory(python) endif () diff --git a/cmake/GoogleTest.CMakeLists.txt.in b/cmake/GoogleTest.CMakeLists.txt.in deleted file mode 100644 index 83bdfd0..0000000 --- a/cmake/GoogleTest.CMakeLists.txt.in +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - URL https://github.com/google/googletest/archive/release-1.8.1.zip - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - ) \ No newline at end of file diff --git a/cmake/pmc.CMakeLists.txt.in b/cmake/pmc.CMakeLists.txt.in deleted file mode 100644 index 220eba0..0000000 --- a/cmake/pmc.CMakeLists.txt.in +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(pmc-download NONE) - -include(ExternalProject) -# Notice that this project uses a forked version of PMC with minor fixes & changes -ExternalProject_Add(pmc - GIT_REPOSITORY https://github.com/jingnanshi/pmc.git - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/pmc-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/pmc-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - ) \ No newline at end of file diff --git a/cmake/spectra.CMakeLists.txt.in b/cmake/spectra.CMakeLists.txt.in deleted file mode 100644 index c4c65f3..0000000 --- a/cmake/spectra.CMakeLists.txt.in +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(spectra-download NONE) - -include(ExternalProject) -ExternalProject_Add(spectral - GIT_REPOSITORY https://github.com/jingnanshi/spectra - GIT_TAG 5c4fb1de050847988faaaaa50f60e7d3d5f16143 - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/spectra-src" - BINARY_DIR "" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - ) \ No newline at end of file diff --git a/cmake/tinyply.CMakeLists.txt.in b/cmake/tinyply.CMakeLists.txt.in deleted file mode 100644 index 52ec469..0000000 --- a/cmake/tinyply.CMakeLists.txt.in +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(tinyply-download NONE) - -include(ExternalProject) -ExternalProject_Add(pmc - GIT_REPOSITORY https://github.com/jingnanshi/tinyply.git - GIT_TAG 0b9fff8e8bd4d37256554fe40cf76b2f3134377b - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/tinyply-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/tinyply-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - ) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 19a2558..80d6424 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,10 +46,15 @@ Homepage = "https://github.com/MIT-SPARK/TEASER-plusplus" [tool.scikit-build] build-dir = "build/{wheel_tag}" -build.verbose = false +build.verbose = true cmake.version = ">=3.16" wheel.install-dir = "teaserpp_python.libs" +[tool.scikit-build.cmake.define] +BUILD_PYTHON_BINDINGS = "ON" +BUILD_TESTS = "OFF" +BUILD_SHARED_LIBS = "OFF" + [tool.cibuildwheel] archs = ["auto64"] skip = ["*-musllinux*", "pp*", "cp36-*"] diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index aa70aaa..4b3bb85 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,26 +1,12 @@ -cmake_minimum_required(VERSION 3.10) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -project(teaser_python_bindings) +find_package(pybind11 REQUIRED) pybind11_add_module(teaserpp_python teaserpp_python/teaserpp_python.cc) - -message(STATUS "Python Interpreter Version: ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") -if (NOT (PYTHON_VERSION_MAJOR EQUAL 2 AND PYTHON_VERSION_MINOR EQUAL 7)) - # Hack: VTK used in PCL might add /usr/include/python2.7 to all targets' - # INCLUDE_DIRECTORIES properties. We need to remove it. - get_target_property(TEASERPY_NEW_INCLUDE_DIRS teaserpp_python INTERFACE_INCLUDE_DIRECTORIES) - list(FILTER TEASERPY_NEW_INCLUDE_DIRS EXCLUDE REGEX ".*python2.7$") - set_target_properties(teaserpp_python - PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${TEASERPY_NEW_INCLUDE_DIRS}") -endif () - target_link_libraries(teaserpp_python PUBLIC teaser_registration) # fix for clang # see: https://github.com/pybind/pybind11/issues/1818 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - target_compile_options(teaserpp_python PUBLIC -fno-sized-deallocation) + target_compile_options(teaserpp_python PUBLIC -fno-sized-deallocation) endif () # make sure to output the build file to teaserpp_python folder @@ -29,35 +15,8 @@ SET_TARGET_PROPERTIES(teaserpp_python OUTPUT_NAME "_teaserpp" PREFIX "" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/teaserpp_python" - INSTALL_RPATH "$ORIGIN/../teaserpp_python.libs/lib;$ORIGIN/../../teaser/" - BUILD_WITH_INSTALL_RPATH TRUE ) -# copy package __init__.py file -configure_file(teaserpp_python/__init__.py - ${CMAKE_CURRENT_BINARY_DIR}/teaserpp_python/__init__.py - ) - -configure_file(teaserpp_python/__init__.py - ${CMAKE_CURRENT_BINARY_DIR}/teaserpp_python/_teaserpp.pyi - ) - -# copy setup.py file -configure_file(setup.py.in - ${CMAKE_CURRENT_BINARY_DIR}/setup.py - ) - -file(COPY . - DESTINATION . - FILES_MATCHING - PATTERN *.py) - if (DEFINED SKBUILD) - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/teaserpp/ - DESTINATION "../teaserpp" - FILES_MATCHING PATTERN "*.py" - PATTERN "*.pyi" - PATTERN "*.so" - ) install(TARGETS teaserpp_python DESTINATION "../teaserpp_python") endif () diff --git a/python/setup.py.in b/python/setup.py.in deleted file mode 100644 index 882ed4e..0000000 --- a/python/setup.py.in +++ /dev/null @@ -1,12 +0,0 @@ -from setuptools import setup - -setup( - name='teaserpp_python', - version='1.0.0', - author='Jingnan Shi', - author_email='jnshi@mit.edu', - description='Python binding for TEASER++', - package_dir={'': '${CMAKE_CURRENT_BINARY_DIR}'}, - packages=['teaserpp_python'], - package_data={'': ['*.so']} -) diff --git a/teaser/CMakeLists.txt b/teaser/CMakeLists.txt index 133ea6a..b96e2f3 100644 --- a/teaser/CMakeLists.txt +++ b/teaser/CMakeLists.txt @@ -1,56 +1,74 @@ -project(teaser_source) include(GNUInstallDirs) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -if (DEFINED SKBUILD) - set(CMAKE_INSTALL_RPATH "$ORIGIN") - set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) -endif () +include(FetchContent) + +FetchContent_Declare(pmc + GIT_REPOSITORY https://github.com/jingnanshi/pmc.git +) +if (NOT pmc_POPULATED) + FetchContent_Populate(pmc) + set(PMC_BUILD_SHARED OFF CACHE INTERNAL "") + add_subdirectory(${pmc_SOURCE_DIR} ${pmc_BINARY_DIR} EXCLUDE_FROM_ALL) +endif() + +FetchContent_Declare(tinyply + GIT_REPOSITORY https://github.com/ddiakopoulos/tinyply.git + BUILD_COMMAND "" + INSTALL_COMMAND "" +) +if (NOT tinyply_POPULATED) + FetchContent_Populate(tinyply) +endif() + +FetchContent_Declare(spectra + GIT_REPOSITORY https://github.com/jingnanshi/spectra + GIT_TAG 5c4fb1de050847988faaaaa50f60e7d3d5f16143 + BUILD_COMMAND "" + INSTALL_COMMAND "" +) +if (NOT spectra_POPULATED) + FetchContent_Populate(spectra) +endif() # teaser_io library -add_library(teaser_io SHARED src/ply_io.cc) -target_link_libraries(teaser_io PRIVATE tinyply) -target_include_directories(teaser_io PUBLIC +add_library(teaser_io src/ply_io.cc) +target_include_directories(teaser_io + PUBLIC $ $ - $) - - -SET_TARGET_PROPERTIES(teaser_io - PROPERTIES - INSTALL_RPATH "$ORIGIN;$ORIGIN/../tinyply-build" - BUILD_WITH_INSTALL_RPATH TRUE + $ + PRIVATE + $ ) +if(NOT BUILD_SHARED_LIBS) + set_property(TARGET teaser_io PROPERTY POSITION_INDEPENDENT_CODE 1) +endif() -install(TARGETS teaser_io - EXPORT teaserpp-export - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - ) -list(APPEND TEASERPP_EXPORTED_TARGETS teaser_io tinyply) add_library(teaserpp::teaser_io ALIAS teaser_io) # teaser_registration library -add_library(teaser_registration SHARED +add_library(teaser_registration src/certification.cc src/registration.cc src/graph.cc - ) - -SET_TARGET_PROPERTIES(teaser_registration - PROPERTIES - INSTALL_RPATH "$ORIGIN;$ORIGIN/../pmc-build" - BUILD_WITH_INSTALL_RPATH TRUE ) + target_link_libraries(teaser_registration PUBLIC Eigen3::Eigen PRIVATE pmc ${TEASERPP_BLAS_LAPACK_LIBS} - ) -target_include_directories(teaser_registration PUBLIC +) +target_include_directories(teaser_registration + PUBLIC $ $ - $ - $) + $ + PRIVATE + $ +) +if(NOT BUILD_SHARED_LIBS) + set_property(TARGET teaser_registration PROPERTY POSITION_INDEPENDENT_CODE 1) +endif() find_package(OpenMP) if(OpenMP_CXX_FOUND) @@ -58,12 +76,6 @@ if(OpenMP_CXX_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") endif() -install(TARGETS teaser_registration - EXPORT teaserpp-export - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) -list(APPEND TEASERPP_EXPORTED_TARGETS teaser_registration pmc) add_library(teaserpp::teaser_registration ALIAS teaser_registration) # teaser_features library @@ -72,15 +84,12 @@ if (BUILD_TEASER_FPFH) add_library(teaser_features SHARED src/fpfh.cc src/matcher.cc - ) + ) target_link_libraries(teaser_features - PRIVATE ${PCL_LIBRARIES} - PRIVATE Eigen3::Eigen - ) + PRIVATE ${PCL_LIBRARIES} Eigen3::Eigen + ) if (BUILD_WITH_MKL AND MKL_FOUND) - target_link_libraries(teaser_features - PRIVATE ${MKL_LIBRARIES} - ) + target_link_libraries(teaser_features PRIVATE ${MKL_LIBRARIES}) endif () target_include_directories(teaser_features PUBLIC $ @@ -103,17 +112,21 @@ if (BUILD_WITH_MARCH_NATIVE) target_compile_options(teaser_registration PUBLIC -march=native) endif () -# set exported targets in parent scope -set(TEASERPP_EXPORTED_TARGETS "${TEASERPP_EXPORTED_TARGETS}" PARENT_SCOPE) - # installation -install(EXPORT teaserpp-export - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/teaserpp - NAMESPACE teaserpp:: - FILE teaserppTargets.cmake -) - if (NOT DEFINED SKBUILD) + install(TARGETS teaser_io teaser_registration + EXPORT teaserpp-export + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + list(APPEND TEASERPP_EXPORTED_TARGETS teaser_io teaser_registration) + set(TEASERPP_EXPORTED_TARGETS "${TEASERPP_EXPORTED_TARGETS}" PARENT_SCOPE) + + install(EXPORT teaserpp-export + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/teaserpp + NAMESPACE teaserpp:: + FILE teaserppTargets.cmake + ) + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - install(DIRECTORY ${SPECTRA_INCLUDE_DIRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif () diff --git a/teaser/src/ply_io.cc b/teaser/src/ply_io.cc index 8bbf406..21ed73e 100644 --- a/teaser/src/ply_io.cc +++ b/teaser/src/ply_io.cc @@ -13,6 +13,8 @@ #include #include "teaser/ply_io.h" + +#define TINYPLY_IMPLEMENTATION #include "tinyply.h" // Internal datatypes for storing ply vertices diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 14ae1e6..7f042c1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,16 @@ project(teaser_all_test) + +include(FetchContent) +FetchContent_Declare(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG main +) +if (NOT googletest_POPULATED) + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_Populate(googletest) + add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) +endif() + include(GoogleTest) add_subdirectory(test-tools)