diff --git a/CMakeLists.txt b/CMakeLists.txt index acaa3a41..f868f619 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,90 +45,139 @@ include(CompilerSettings) include(FetchInitCPM) include(Dependencies) -list(APPEND VAMP_EXT_SOURCES - src/impl/vamp/bindings/python.cc - src/impl/vamp/bindings/environment.cc - src/impl/vamp/bindings/settings.cc +list(APPEND VAMP_INCLUDES + src/impl ) -list(APPEND VAMP_ROBOT_MODULES - sphere - ur5 - panda - fetch - baxter +# Header-only C++ library +include(GNUInstallDirs) +add_library(vamp INTERFACE) +target_include_directories(vamp INTERFACE + $ + $ ) -foreach(robot_name IN LISTS VAMP_ROBOT_MODULES) - list(APPEND VAMP_EXT_SOURCES "src/impl/vamp/bindings/${robot_name}.cc") -endforeach() +target_compile_features(vamp INTERFACE cxx_std_17) +target_link_libraries(vamp INTERFACE Eigen3::Eigen nigh::nigh pdqsort::pdqsort) +install(TARGETS vamp + EXPORT ${PROJECT_NAME}_Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) -list(APPEND VAMP_EXT_INCLUDES - ${NIGH_INCLUDE_DIRS} - ${PDQSORT_INCLUDE_DIRS} - src/impl +include(CMakePackageConfigHelpers) +write_basic_package_version_file("vampConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion ) -nanobind_add_module(_core_ext - NB_STATIC - STABLE_ABI - NOMINSIZE - ${VAMP_EXT_SOURCES} +configure_package_config_file("${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake ) -target_include_directories(_core_ext - SYSTEM PRIVATE - ${VAMP_EXT_INCLUDES} +install(EXPORT ${PROJECT_NAME}_Targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake ) -target_link_libraries(_core_ext - PRIVATE - Eigen3::Eigen +install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake ) -if($ENV{GITHUB_ACTIONS}) - set(STUB_PREFIX "") -else() - set(STUB_PREFIX "${CMAKE_BINARY_DIR}/stubs/") -endif() +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/vamp DESTINATION include) -nanobind_add_stub( - vamp_stub - MODULE _core_ext - OUTPUT "${STUB_PREFIX}__init__.pyi" - PYTHON_PATH $ - DEPENDS _core_ext - VERBOSE -) +# Python extension +option(VAMP_BUILD_PYTHON_BINDINGS "Build Python VAMP extensions" OFF) +if(VAMP_BUILD_PYTHON_BINDINGS) + find_package(Python 3.8 + REQUIRED COMPONENTS Interpreter Development.Module + OPTIONAL_COMPONENTS Development.SABIModule) + + CPMAddPackage("gh:wjakob/nanobind#358d452c314dbe8c07026d984ad8d5aa860f26fb") + + list(APPEND VAMP_EXT_SOURCES + src/impl/vamp/bindings/python.cc + src/impl/vamp/bindings/environment.cc + src/impl/vamp/bindings/settings.cc + ) + + list(APPEND VAMP_ROBOT_MODULES + sphere + ur5 + panda + fetch + baxter + ) + + foreach(robot_name IN LISTS VAMP_ROBOT_MODULES) + list(APPEND VAMP_EXT_SOURCES "src/impl/vamp/bindings/${robot_name}.cc") + endforeach() + + nanobind_add_module(_core_ext + NB_STATIC + STABLE_ABI + NOMINSIZE + ${VAMP_EXT_SOURCES} + ) + + target_include_directories(_core_ext + SYSTEM PRIVATE + ${VAMP_INCLUDES} + ) + + target_link_libraries(_core_ext + PRIVATE + Eigen3::Eigen + ) + + if($ENV{GITHUB_ACTIONS}) + set(STUB_PREFIX "") + else() + set(STUB_PREFIX "${CMAKE_BINARY_DIR}/stubs/") + endif() -foreach(robot_name IN LISTS VAMP_ROBOT_MODULES) nanobind_add_stub( - "vamp_${robot_name}_stub" - MODULE "_core_ext.${robot_name}" - OUTPUT "${STUB_PREFIX}${robot_name}.pyi" + vamp_stub + MODULE _core_ext + OUTPUT "${STUB_PREFIX}__init__.pyi" PYTHON_PATH $ DEPENDS _core_ext VERBOSE ) -endforeach() -install( - TARGETS _core_ext - LIBRARY - DESTINATION vamp/_core -) + foreach(robot_name IN LISTS VAMP_ROBOT_MODULES) + nanobind_add_stub( + "vamp_${robot_name}_stub" + MODULE "_core_ext.${robot_name}" + OUTPUT "${STUB_PREFIX}${robot_name}.pyi" + PYTHON_PATH $ + DEPENDS _core_ext + VERBOSE + ) + endforeach() -install( - FILES "${STUB_PREFIX}__init__.pyi" - DESTINATION "${CMAKE_SOURCE_DIR}/src/vamp/_core" -) + install( + TARGETS _core_ext + LIBRARY + DESTINATION vamp/_core + ) -foreach(robot_name IN LISTS VAMP_ROBOT_MODULES) install( - FILES "${STUB_PREFIX}${robot_name}.pyi" + FILES "${STUB_PREFIX}__init__.pyi" DESTINATION "${CMAKE_SOURCE_DIR}/src/vamp/_core" ) -endforeach() + + foreach(robot_name IN LISTS VAMP_ROBOT_MODULES) + install( + FILES "${STUB_PREFIX}${robot_name}.pyi" + DESTINATION "${CMAKE_SOURCE_DIR}/src/vamp/_core" + ) + endforeach() +endif() if(VAMP_BUILD_OMPL_DEMO) find_package(ompl QUIET PATHS ${VAMP_OMPL_PATH}) @@ -136,7 +185,7 @@ if(VAMP_BUILD_OMPL_DEMO) if(ompl_FOUND) add_executable(vamp_ompl_integration scripts/cpp/ompl_integration.cc) target_link_libraries(vamp_ompl_integration PRIVATE ompl::ompl Eigen3::Eigen) - target_include_directories(vamp_ompl_integration SYSTEM PRIVATE ${VAMP_EXT_INCLUDES}) + target_include_directories(vamp_ompl_integration SYSTEM PRIVATE ${VAMP_INCLUDES}) else() message(WARNING "OMPL not found! Cannot build OMPL demo.") endif() diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 7b3c5ca3..61de5946 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -1,16 +1,42 @@ find_package(Eigen3 REQUIRED NO_MODULE) -find_package(Python 3.8 - REQUIRED COMPONENTS Interpreter Development.Module - OPTIONAL_COMPONENTS Development.SABIModule) - -CPMAddPackage("gh:wjakob/nanobind#358d452c314dbe8c07026d984ad8d5aa860f26fb") CPMAddPackage("gh:kavrakilab/nigh#97130999440647c204e0265d05a997dbd8da4e70") -set(NIGH_INCLUDE_DIRS ${nigh_SOURCE_DIR}/src) +if(nigh_ADDED) + add_library(nigh INTERFACE) + target_include_directories(nigh INTERFACE $) + install(TARGETS nigh + EXPORT nigh_TARGETS + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + install(EXPORT nigh_TARGETS FILE nighTargets.cmake NAMESPACE nigh:: DESTINATION + ${CMAKE_INSTALL_LIBDIR}/cmake/nigh) + export(EXPORT nigh_TARGETS FILE ${CMAKE_CURRENT_BINARY_DIR}/cmake/nighTargets.cmake NAMESPACE nigh::) +else() + message(FATAL_ERROR "Could not install required dependency: nigh") +endif() CPMAddPackage("gh:orlp/pdqsort#b1ef26a55cdb60d236a5cb199c4234c704f46726") -set(PDQSORT_INCLUDE_DIRS ${pdqsort_SOURCE_DIR}) +if(pdqsort_ADDED) + add_library(pdqsort INTERFACE) + target_include_directories(pdqsort INTERFACE $) + install(TARGETS pdqsort + EXPORT pdqsort_TARGETS + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + install(EXPORT pdqsort_TARGETS FILE pdqsortTargets.cmake NAMESPACE pdqsort:: DESTINATION + ${CMAKE_INSTALL_LIBDIR}/cmake/pdqsort) + export(EXPORT pdqsort_TARGETS FILE ${CMAKE_CURRENT_BINARY_DIR}/cmake/pdqsortTargets.cmake NAMESPACE pdqsort::) +else() + message(FATAL_ERROR "Could not install required dependency: pdqsort") +endif() +# TODO: Handle including this in the C++ library if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") CPMAddPackage("gh:lemire/SIMDxorshift#857c1a01df53cf1ee1ae8db3238f0ef42ef8e490") list(APPEND VAMP_EXT_SOURCES diff --git a/cmake/vampConfig.cmake.in b/cmake/vampConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/cmake/vampConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/pyproject.toml b/pyproject.toml index f1e0f51e..08aff88e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,3 +35,4 @@ cmake.build-type = "Release" [tool.scikit-build.cmake.define] VAMP_LTO = "ON" # VAMP_FORCE_CLANG = "ON" +VAMP_BUILD_PYTHON_BINDINGS = ON