cmake_minimum_required(VERSION 3.16) project(iDynTreeBindings) # Detect if we are doing a standalone build of the bindings, using an external iDynTree if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(IDYNTREE_BINDINGS_BUILD_STANDALONE TRUE) else() set(IDYNTREE_BINDINGS_BUILD_STANDALONE FALSE) endif() if(IDYNTREE_BINDINGS_BUILD_STANDALONE) # Add CMake helpers list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake) find_package(iDynTree REQUIRED) set(IDYNTREE_LIBRARIES ${iDynTree_LIBRARIES}) # Set variables that are set in extern get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) set(IDYNTREE_INTERNAL_MOXUNIT_PATH "${PARENT_DIR}/extern/MOxUnit/MOxUnit") set(IDYNTREE_INTERNAL_MESH2TRI_PATH "${PARENT_DIR}/extern/mesh2tri") else() get_property(IDYNTREE_LIBRARIES GLOBAL PROPERTY ${VARS_PREFIX}_TARGETS) endif() ############################################################################# ## Options for compiling supported languages. There's nothing magical ## about this list, any SWIG-supported language should work - take a ## look at e.g. ruby code below for how to do it. option(IDYNTREE_USES_PYTHON "Do you want to create the Python bindings" FALSE) option(IDYNTREE_USES_LUA "Do you want to create the Lua bindings" FALSE) option(IDYNTREE_USES_MATLAB "Do you want to create the MATLAB bindings" FALSE) option(IDYNTREE_USES_OCTAVE "Do you want to create the OCTAVE bindings" FALSE) option(IDYNTREE_GENERATE_MATLAB "Enable if you have the experimental version of SWIG necessary for generating the Matlab wrapper" FALSE) option(IDYNTREE_DETECT_ACTIVE_PYTHON_SITEPACKAGES "Do you want iDynTree to detect and install in the active site-package directory? (it could be a system dir)" FALSE) find_package(SWIG) if(IDYNTREE_USES_PYTHON OR IDYNTREE_USES_PYTHON_PYBIND11) if(${CMAKE_VERSION} VERSION_LESS "3.18.0") set(IDYNTREE_SEARCHED_Python_Development_Component "Development") else() set(IDYNTREE_SEARCHED_Python_Development_Component "Development.Module") endif() find_package(Python3 COMPONENTS Interpreter ${IDYNTREE_SEARCHED_Python_Development_Component} NumPy REQUIRED) if (IDYNTREE_DETECT_ACTIVE_PYTHON_SITEPACKAGES) set(PYTHON_INSTDIR ${Python3_SITELIB}/idyntree) elseif(IDYNTREE_PACKAGE_FOR_PYPI) set(PYTHON_INSTDIR ${CMAKE_INSTALL_PREFIX}) else() execute_process(COMMAND ${Python3_EXECUTABLE} -c "from distutils import sysconfig; print(sysconfig.get_python_lib(1,0,prefix=''))" OUTPUT_VARIABLE _PYTHON_INSTDIR) string(STRIP ${_PYTHON_INSTDIR} IDYNTREE_PYTHON_INSTALL_DIR) set(PYTHON_INSTDIR ${IDYNTREE_PYTHON_INSTALL_DIR}/idyntree) endif() endif() # It is possible to compile matlab/octave bindings without using SWIG if(SWIG_FOUND OR IDYNTREE_USES_MATLAB OR IDYNTREE_USES_OCTAVE) if(EXISTS ${SWIG_USE_FILE}) include(${SWIG_USE_FILE}) else() include(UseSWIG) endif() set_source_files_properties(iDynTree.i PROPERTIES CPLUSPLUS ON) # From https://github.com/robotology/yarp/blob/v3.3.0/bindings/CMakeLists.txt#L49 foreach(_lib IN LISTS IDYNTREE_LIBRARIES) get_property(_include_dirs TARGET ${_lib} PROPERTY INTERFACE_INCLUDE_DIRECTORIES) foreach(_dir IN LISTS _include_dirs) if("${_dir}" MATCHES "\$$") include_directories("${CMAKE_MATCH_1}") elseif("${_dir}" MATCHES "\$$") # Nothing to do else() include_directories(${_dir}) endif() endforeach() endforeach() link_libraries(${IDYNTREE_LIBRARIES}) if(NOT IDYNTREE_BINDINGS_BUILD_STANDALONE) # Remove the deprecation warnings because by definition we always build bindings also of deprecated modules idyntree_disable_deprecation_warnings() endif() # list all dependencies of the process of generating # SWIG bindings (for now just .i files included in the main # iDynTree.i file) # This will not be necessary once http://public.kitware.com/Bug/view.php?id=4147 # is resolved # (not working at the moment, todo \TODO fix) set(IDYNTREE_SWIG_DEPENDS_I_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ignore.i ${CMAKE_CURRENT_SOURCE_DIR}/sensors.i) if(IDYNTREE_USES_LUA) add_subdirectory(lua) endif(IDYNTREE_USES_LUA) if(IDYNTREE_USES_PYTHON) add_subdirectory(python) endif(IDYNTREE_USES_PYTHON) if(IDYNTREE_USES_MATLAB OR IDYNTREE_GENERATE_MATLAB OR IDYNTREE_USES_OCTAVE) add_subdirectory(matlab) endif() endif() if(IDYNTREE_USES_PYTHON OR IDYNTREE_USES_LUA OR IDYNTREE_GENERATED_MATLAB) if(NOT SWIG_FOUND) MESSAGE(FATAL_ERROR "Swig not found, impossible to compile or generate iDynTree bindings.") endif() endif() option(IDYNTREE_USES_PYTHON_PYBIND11 "Create iDynTree Python bindings using pybind11" FALSE) if (IDYNTREE_USES_PYTHON_PYBIND11) find_package(pybind11 REQUIRED) add_subdirectory(pybind11) endif() # Install main __init__.py file. if (IDYNTREE_USES_PYTHON_PYBIND11 OR IDYNTREE_USES_PYTHON) if (WIN32) set(NEW_LINE "\n\r") else() set(NEW_LINE "\n") endif() # Clear the file first if it exists. file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/__init__.py "") # If pybind is enabled, add the corresponding import. if (${IDYNTREE_USES_PYTHON_PYBIND11}) file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/__init__.py "from . import pybind${NEW_LINE}") endif() # If SWIG is enabled, add the corresponding import. if (${IDYNTREE_USES_PYTHON}) file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" "from . import swig${NEW_LINE}from . import visualize${NEW_LINE}") # Create also an alias from swig to the old `bindings` import. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bindings.py" "from .swig import *${NEW_LINE}") install( FILES "${CMAKE_CURRENT_BINARY_DIR}/bindings.py" DESTINATION ${PYTHON_INSTDIR} COMPONENT python) # Add the alias in the __init__.py file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" "from . import bindings${NEW_LINE}") endif() install( FILES "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" DESTINATION ${PYTHON_INSTDIR} COMPONENT python) endif()