cmake_minimum_required(VERSION 3.6) include(ExternalProject) # We use a function to enforce a scoped variables creation only for the build # (i.e turn off BUILD_SHARED_LIBS which is used on LRS build as well) function(get_pybind11) message( STATUS #CHECK_START "Fetching pybind11..." ) #list( APPEND CMAKE_MESSAGE_INDENT " " ) # Indent outputs # We want to clone the pybind repo and build it here, during configuration, so we can use it. # But ExternalProject_add is limited in that it only does its magic during build. # This is possible in CMake 3.12+ with FetchContent and FetchContent_MakeAvailable in 3.14+ (meaning Ubuntu 20) # but we need to adhere to CMake 3.10 (Ubuntu 18). # So instead, we invoke a new CMake project just to download pybind: configure_file( CMake/pybind11-download.cmake.in ${CMAKE_BINARY_DIR}/external-projects/pybind11-download/CMakeLists.txt ) execute_process( COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/external-projects/pybind11-download" OUTPUT_QUIET RESULT_VARIABLE configure_ret ) execute_process( COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/external-projects/pybind11-download" OUTPUT_QUIET RESULT_VARIABLE build_ret ) if( configure_ret OR build_ret ) message( FATAL_ERROR "Failed to download pybind11" ) endif() # Now that it's available, we can refer to it with an actual ExternalProject_add (but notice we're not # downloading anything) ExternalProject_Add( pybind11 PREFIX ${CMAKE_BINARY_DIR}/external-projects/pybind11 # just so it doesn't use build/pybind11-prefix SOURCE_DIR ${CMAKE_BINARY_DIR}/third-party/pybind11 BINARY_DIR ${CMAKE_BINARY_DIR}/third-party/pybind11/build CMAKE_ARGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} -DBUILD_SHARED_LIBS=OFF # Suppress warnings that are meant for the author of the CMakeLists.txt files -Wno-dev # Just in case! -DPYBIND11_INSTALL=OFF -DPYBIND11_TEST=OFF INSTALL_COMMAND "" UPDATE_COMMAND "" PATCH_COMMAND "" TEST_COMMAND "" ) add_subdirectory( "${CMAKE_BINARY_DIR}/third-party/pybind11" "${CMAKE_BINARY_DIR}/third-party/pybind11/build" ) set_target_properties( pybind11 PROPERTIES FOLDER "3rd Party" ) # Besides pybind11, any python module will also need to be installed using: # install( # TARGETS ${PROJECT_NAME} # EXPORT pyrealsense2Targets # LIBRARY DESTINATION ${PYTHON_INSTALL_DIR} # ARCHIVE DESTINATION ${PYTHON_INSTALL_DIR} # ) # But, to do this, we need to define PYTHON_INSTALL_DIR! if( CMAKE_VERSION VERSION_LESS 3.12 ) find_package(PythonInterp REQUIRED) find_package(PythonLibs REQUIRED) set( PYTHON_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/pyrealsense2" CACHE PATH "Installation directory for Python bindings") else() find_package(Python REQUIRED COMPONENTS Interpreter Development) set( PYTHON_INSTALL_DIR "${Python_SITEARCH}/pyrealsense2" CACHE PATH "Installation directory for Python bindings") endif() message( STATUS #CHECK_PASS "Fetching pybind11 - Done" ) #list( POP_BACK CMAKE_MESSAGE_INDENT ) # Unindent outputs (requires cmake 3.15) endfunction() # We also want a json-compatible pybind interface: function(get_pybind11_json) message( STATUS #CHECK_START "Fetching pybind11_json..." ) #list( APPEND CMAKE_MESSAGE_INDENT " " ) # Indent outputs # We want to clone the pybind repo and build it here, during configuration, so we can use it. # But ExternalProject_add is limited in that it only does its magic during build. # This is possible in CMake 3.12+ with FetchContent and FetchContent_MakeAvailable in 3.14+ (meaning Ubuntu 20) # but we need to adhere to CMake 3.10 (Ubuntu 18). # So instead, we invoke a new CMake project just to download pybind: configure_file( CMake/pybind11-json-download.cmake.in ${CMAKE_BINARY_DIR}/external-projects/pybind11-json-download/CMakeLists.txt ) execute_process( COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/external-projects/pybind11-json-download" OUTPUT_QUIET RESULT_VARIABLE configure_ret ) execute_process( COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/external-projects/pybind11-json-download" OUTPUT_QUIET RESULT_VARIABLE build_ret ) if( configure_ret OR build_ret ) message( FATAL_ERROR "Failed to download pybind11_json" ) endif() # pybind11_add_module will add the directory automatically (see below) message( STATUS #CHECK_PASS "Fetching pybind11_json - Done" ) #list( POP_BACK CMAKE_MESSAGE_INDENT ) # Unindent outputs (requires cmake 3.15) endfunction() # Trigger the build get_pybind11() get_pybind11_json() # This function overrides "pybind11_add_module" function, arguments is same as "pybind11_add_module" arguments # pybind11_add_module( SHARED [file, file2, ...] ) # Must be declared after pybind11 configuration above function( pybind11_add_module project_name library_type ...) # message( STATUS "adding python module --> ${project_name}" # "_pybind11_add_module" is calling the origin pybind11 function _pybind11_add_module( ${ARGV}) # Force Pybind11 not to share pyrealsense2 resources with other pybind modules. # With this definition we force the ABI version to be unique and not risk crashes on different modules. # (workaround for RS5-10582; see also https://github.com/pybind/pybind11/issues/2898) # NOTE: this workaround seems to be needed for debug compilations only target_compile_definitions( ${project_name} PRIVATE -DPYBIND11_COMPILER_TYPE=\"_${project_name}_abi\" ) target_include_directories( ${project_name} PRIVATE "${CMAKE_BINARY_DIR}/third-party/pybind11-json/include" ) endfunction()