diff --git a/CMakeLists.txt b/CMakeLists.txt index 7348c6f..c240bea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,12 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.15) -project(xbot2_interface LANGUAGES CXX VERSION 1.0.0) +project(xbot2_interface LANGUAGES CXX) +file(READ "VERSION" PROJECT_VERSION) + +string(REPLACE "." ";" PARTS ${PROJECT_VERSION}) +list(GET PARTS 0 xbot2_interface_VERSION_MAJOR) +list(GET PARTS 1 xbot2_interface_VERSION_MINOR) +list(GET PARTS 2 xbot2_interface_VERSION_PATCH) option(XBOT2_IFC_BUILD_PINOCCHIO "Build Pinocchio implementation" ON) option(XBOT2_IFC_BUILD_RBDL "Build RBDL implementation" OFF) @@ -8,11 +14,17 @@ option(XBOT2_IFC_BUILD_ROS "Build ROS implementation" ON) option(XBOT2_IFC_BUILD_ROS2 "Build ROS2 implementation" OFF) option(XBOT2_IFC_BUILD_COLLISION "Build collision support (required hpp-fcl)" ON) option(XBOT2_IFC_BUILD_TESTS "Build tests" OFF) +option(XBOT2_IFC_BUILD_EXAMPLES "Build examples" OFF) +option(COMPILE_PYTHON_BINDINGS "Compile python bindings (requires pybind11)" ON) +option(BUILD_BY_PYTHON "Indicate that cmake is invoked by python build tools" OFF) +# Defaulted to ON since it would change behaviour +option(USE_SHLIBDEPS "Use dpkg-shlibdebs for deb generation. It needs a previous install before packaging; therefore makes only sense in a CD job" ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_INSTALL_RPATH $ORIGIN) +# This explicit opt path helps pyxbot2 libs to find the actual implementations from anywhere (especially a venv) +set(CMAKE_INSTALL_RPATH "$ORIGIN;/opt/xbot/lib") set(CMAKE_BUILD_RPATH "$ORIGIN;$ORIGIN/pinocchio;$ORIGIN/rbdl;$ORIGIN/ros") find_package(urdf REQUIRED) @@ -109,7 +121,6 @@ install(DIRECTORY include/xbot2_interface DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xbot2_interface ) - if(${XBOT2_IFC_BUILD_PINOCCHIO}) add_subdirectory(pinocchio/) endif() @@ -130,9 +141,13 @@ if(${XBOT2_IFC_BUILD_COLLISION}) add_subdirectory(src/collision/) endif() -add_subdirectory(python) +if(${COMPILE_PYTHON_BINDINGS}) + add_subdirectory(python) +endif() -add_subdirectory(examples) +if(${XBOT2_IFC_BUILD_EXAMPLES}) + add_subdirectory(examples) +endif() if(${XBOT2_IFC_BUILD_TESTS}) enable_testing() diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/cmake/GenerateDeb.cmake b/cmake/GenerateDeb.cmake index ae2e8de..edf5d36 100644 --- a/cmake/GenerateDeb.cmake +++ b/cmake/GenerateDeb.cmake @@ -11,8 +11,16 @@ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Set of APIs for robot control and modeling # dependencies set(CPACK_DEBIAN_PACKAGE_DEPENDS "") -set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) -set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) +# Would be nice to have that especially because it will be hard to put the dependencies above +# but it does not help if it does not work properly. +# OpenCV guys have the same problem https://github.com/opencv/opencv/issues/16318 +# dpkg-shlibdeps looks into the /opt/xbot path although there is nothing, YET +# Packaging after installing makes literally no sense. +# This is probably (STILL) a cmake/cpack problem +if (${USE_SHLIBDEPS}) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) +endif() # get short sha1 of current commit from git find_program(GIT_SCM git DOC "Git version control") diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..aa884da --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,21 @@ +[build-system] +requires = ["scikit-build-core>=0.3.0", "pybind11", "numpy~=1.26"] +build-backend = "scikit_build_core.build" + +[project] +name = "xbot2_interface" +dynamic = ["version"] +dependencies = ["numpy~=1.26"] + +[tool.scikit-build] +install.components = ["python-bindings"] +cmake.source-dir = "." +cmake.build-type = "Release" +build.targets = ["pyxbot2_interface", "pyaffine3"] +cmake.define = { "BUILD_BY_PYTHON"="ON" } + +[tool.scikit-build.metadata.version] +provider = "scikit_build_core.metadata.regex" +input = "VERSION" +regex = "(?P\\d+).(?P\\d+).(?P\\d+)" +result = "{major}.{minor}.{patch}" diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index e20b2f1..9b74e60 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,20 +1,22 @@ cmake_policy(SET CMP0094 NEW) -find_package(Python3 COMPONENTS Interpreter Development) +find_package(Python3 COMPONENTS Interpreter Development.Module NumPy) find_package(pybind11 QUIET) -option(COMPILE_PYTHON_BINDINGS "Compile python bindings (requires pybind11)" TRUE) - -if(${pybind11_FOUND} AND ${COMPILE_PYTHON_BINDINGS}) +if(${pybind11_FOUND}) message(STATUS "Found python (${Python3_EXECUTABLE}) will compile python bindings") - # get python install path - execute_process( - COMMAND ${Python3_EXECUTABLE} -c "import site, os; print(os.path.relpath(site.USER_SITE, site.USER_BASE))" - OUTPUT_VARIABLE PYTHON_SITE - OUTPUT_STRIP_TRAILING_WHITESPACE) + if("${BUILD_BY_PYTHON}") + set(PYTHON_SITE ".") + else() + # get python install path + execute_process( + COMMAND ${Python3_EXECUTABLE} -c "import site, os; print(os.path.relpath(site.USER_SITE, site.USER_BASE))" + OUTPUT_VARIABLE PYTHON_SITE + OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "Python install dir: ${PYTHON_SITE}") + message(STATUS "Python install dir: ${PYTHON_SITE}") + endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -24,7 +26,9 @@ if(${pybind11_FOUND} AND ${COMPILE_PYTHON_BINDINGS}) target_link_libraries(pyxbot2_interface PUBLIC xbot2_interface) install(TARGETS pyxbot2_interface - DESTINATION ${PYTHON_SITE}/xbot2_interface) + DESTINATION ${PYTHON_SITE}/xbot2_interface + COMPONENT python-bindings + ) pybind11_add_module(pyaffine3 pyaffine3.cpp) @@ -32,7 +36,9 @@ if(${pybind11_FOUND} AND ${COMPILE_PYTHON_BINDINGS}) target_link_libraries(pyaffine3 PUBLIC Eigen3::Eigen) install(TARGETS pyaffine3 - DESTINATION ${PYTHON_SITE}/xbot2_interface) + DESTINATION ${PYTHON_SITE}/xbot2_interface + COMPONENT python-bindings + ) if (${XBOT2_IFC_BUILD_COLLISION}) pybind11_add_module(pyxbot2_collision pyxbot2_collision.cpp) @@ -40,9 +46,16 @@ if(${pybind11_FOUND} AND ${COMPILE_PYTHON_BINDINGS}) target_link_libraries(pyxbot2_collision PUBLIC xbot2_interface::collision) install(TARGETS pyxbot2_collision - DESTINATION ${PYTHON_SITE}/xbot2_interface) + DESTINATION ${PYTHON_SITE}/xbot2_interface + COMPONENT python-bindings + ) endif() - install(FILES __init__.py DESTINATION ${PYTHON_SITE}/xbot2_interface) + install(FILES __init__.py DESTINATION ${PYTHON_SITE}/xbot2_interface COMPONENT python-bindings) +else() + if(${BUILD_BY_PYTHON}) + # Fail explicitely as python bindings are needed for building by python + message(FATAL_ERROR "pybind11 not found - cannot build library") + endif() endif()