CMakeLists.txt 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. set(GTSAM_PYTHON_BUILD_DIRECTORY ${PROJECT_BINARY_DIR}/python)
  2. if (NOT GTSAM_BUILD_PYTHON)
  3. return()
  4. endif()
  5. # Generate setup.py.
  6. file(READ "${PROJECT_SOURCE_DIR}/README.md" README_CONTENTS)
  7. configure_file(${PROJECT_SOURCE_DIR}/python/setup.py.in
  8. ${GTSAM_PYTHON_BUILD_DIRECTORY}/setup.py)
  9. # Supply MANIFEST.in for older versions of Python
  10. file(COPY ${PROJECT_SOURCE_DIR}/python/MANIFEST.in
  11. DESTINATION ${GTSAM_PYTHON_BUILD_DIRECTORY})
  12. set(WRAP_BUILD_TYPE_POSTFIXES ${GTSAM_BUILD_TYPE_POSTFIXES})
  13. include(PybindWrap)
  14. ############################################################
  15. ## Load the necessary files to compile the wrapper
  16. # Load the pybind11 code
  17. add_subdirectory(${PROJECT_SOURCE_DIR}/wrap/pybind11 pybind11)
  18. # Set the wrapping script variable
  19. set(PYBIND_WRAP_SCRIPT "${PROJECT_SOURCE_DIR}/wrap/scripts/pybind_wrap.py")
  20. ############################################################
  21. add_custom_target(gtsam_header DEPENDS "${PROJECT_SOURCE_DIR}/gtsam/gtsam.i")
  22. add_custom_target(gtsam_unstable_header DEPENDS "${PROJECT_SOURCE_DIR}/gtsam_unstable/gtsam_unstable.i")
  23. # ignoring the non-concrete types (type aliases)
  24. set(ignore
  25. gtsam::Point2
  26. gtsam::Point3
  27. gtsam::LieVector
  28. gtsam::LieMatrix
  29. gtsam::ISAM2ThresholdMapValue
  30. gtsam::FactorIndices
  31. gtsam::FactorIndexSet
  32. gtsam::IndexPairSetMap
  33. gtsam::IndexPairVector
  34. gtsam::BetweenFactorPose2s
  35. gtsam::BetweenFactorPose3s
  36. gtsam::Point2Vector
  37. gtsam::Point2Pairs
  38. gtsam::Point3Pairs
  39. gtsam::Pose3Pairs
  40. gtsam::Pose3Vector
  41. gtsam::KeyVector
  42. gtsam::BinaryMeasurementsUnit3
  43. gtsam::KeyPairDoubleMap)
  44. set(interface_headers
  45. ${PROJECT_SOURCE_DIR}/gtsam/gtsam.i
  46. ${PROJECT_SOURCE_DIR}/gtsam/base/base.i
  47. ${PROJECT_SOURCE_DIR}/gtsam/geometry/geometry.i
  48. ${PROJECT_SOURCE_DIR}/gtsam/linear/linear.i
  49. ${PROJECT_SOURCE_DIR}/gtsam/nonlinear/nonlinear.i
  50. ${PROJECT_SOURCE_DIR}/gtsam/symbolic/symbolic.i
  51. ${PROJECT_SOURCE_DIR}/gtsam/sam/sam.i
  52. ${PROJECT_SOURCE_DIR}/gtsam/slam/slam.i
  53. ${PROJECT_SOURCE_DIR}/gtsam/sfm/sfm.i
  54. ${PROJECT_SOURCE_DIR}/gtsam/navigation/navigation.i
  55. ${PROJECT_SOURCE_DIR}/gtsam/basis/basis.i
  56. )
  57. set(GTSAM_PYTHON_TARGET gtsam_py)
  58. set(GTSAM_PYTHON_UNSTABLE_TARGET gtsam_unstable_py)
  59. pybind_wrap(${GTSAM_PYTHON_TARGET} # target
  60. "${interface_headers}" # interface_headers
  61. "gtsam.cpp" # generated_cpp
  62. "gtsam" # module_name
  63. "gtsam" # top_namespace
  64. "${ignore}" # ignore_classes
  65. ${PROJECT_SOURCE_DIR}/python/gtsam/gtsam.tpl
  66. gtsam # libs
  67. "gtsam;gtsam_header" # dependencies
  68. ON # use_boost
  69. )
  70. set_target_properties(${GTSAM_PYTHON_TARGET} PROPERTIES
  71. INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"
  72. INSTALL_RPATH_USE_LINK_PATH TRUE
  73. OUTPUT_NAME "gtsam"
  74. LIBRARY_OUTPUT_DIRECTORY "${GTSAM_PYTHON_BUILD_DIRECTORY}/gtsam"
  75. DEBUG_POSTFIX "" # Otherwise you will have a wrong name
  76. RELWITHDEBINFO_POSTFIX "" # Otherwise you will have a wrong name
  77. )
  78. # Set the path for the GTSAM python module
  79. set(GTSAM_MODULE_PATH ${GTSAM_PYTHON_BUILD_DIRECTORY}/gtsam)
  80. # Copy all python files to build folder.
  81. copy_directory("${CMAKE_CURRENT_SOURCE_DIR}/gtsam"
  82. "${GTSAM_MODULE_PATH}")
  83. # Hack to get python test files copied every time they are modified
  84. file(GLOB GTSAM_PYTHON_TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gtsam/tests/*.py")
  85. foreach(test_file ${GTSAM_PYTHON_TEST_FILES})
  86. configure_file(${test_file} "${GTSAM_MODULE_PATH}/tests/${test_file}" COPYONLY)
  87. endforeach()
  88. # Common directory for data/datasets stored with the package.
  89. # This will store the data in the Python site package directly.
  90. file(COPY "${GTSAM_SOURCE_DIR}/examples/Data" DESTINATION "${GTSAM_MODULE_PATH}")
  91. # Add gtsam as a dependency to the install target
  92. set(GTSAM_PYTHON_DEPENDENCIES ${GTSAM_PYTHON_TARGET})
  93. if(GTSAM_UNSTABLE_BUILD_PYTHON)
  94. set(ignore
  95. gtsam::Point2
  96. gtsam::Point3
  97. gtsam::LieVector
  98. gtsam::LieMatrix
  99. gtsam::ISAM2ThresholdMapValue
  100. gtsam::FactorIndices
  101. gtsam::FactorIndexSet
  102. gtsam::BetweenFactorPose3s
  103. gtsam::Point2Vector
  104. gtsam::Pose3Vector
  105. gtsam::KeyVector
  106. gtsam::FixedLagSmootherKeyTimestampMapValue
  107. gtsam::BinaryMeasurementsUnit3
  108. gtsam::CameraSetCal3_S2
  109. gtsam::CameraSetCal3Bundler
  110. gtsam::CameraSetCal3Unified
  111. gtsam::CameraSetCal3Fisheye
  112. gtsam::KeyPairDoubleMap)
  113. pybind_wrap(${GTSAM_PYTHON_UNSTABLE_TARGET} # target
  114. ${PROJECT_SOURCE_DIR}/gtsam_unstable/gtsam_unstable.i # interface_header
  115. "gtsam_unstable.cpp" # generated_cpp
  116. "gtsam_unstable" # module_name
  117. "gtsam" # top_namespace
  118. "${ignore}" # ignore_classes
  119. ${PROJECT_SOURCE_DIR}/python/gtsam_unstable/gtsam_unstable.tpl
  120. gtsam_unstable # libs
  121. "gtsam_unstable;gtsam_unstable_header" # dependencies
  122. ON # use_boost
  123. )
  124. set_target_properties(${GTSAM_PYTHON_UNSTABLE_TARGET} PROPERTIES
  125. INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"
  126. INSTALL_RPATH_USE_LINK_PATH TRUE
  127. OUTPUT_NAME "gtsam_unstable"
  128. LIBRARY_OUTPUT_DIRECTORY "${GTSAM_PYTHON_BUILD_DIRECTORY}/gtsam_unstable"
  129. DEBUG_POSTFIX "" # Otherwise you will have a wrong name
  130. RELWITHDEBINFO_POSTFIX "" # Otherwise you will have a wrong name
  131. )
  132. set(GTSAM_UNSTABLE_MODULE_PATH ${GTSAM_PYTHON_BUILD_DIRECTORY}/gtsam_unstable)
  133. # Copy all python files to build folder.
  134. copy_directory("${CMAKE_CURRENT_SOURCE_DIR}/gtsam_unstable"
  135. "${GTSAM_UNSTABLE_MODULE_PATH}")
  136. # Hack to get python test files copied every time they are modified
  137. file(GLOB GTSAM_UNSTABLE_PYTHON_TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gtsam_unstable/tests/*.py")
  138. foreach(test_file ${GTSAM_PYTHON_TEST_FILES})
  139. configure_file(${test_file} "${GTSAM_UNSTABLE_MODULE_PATH}/tests/${test_file}" COPYONLY)
  140. endforeach()
  141. # Add gtsam_unstable to the install target
  142. list(APPEND GTSAM_PYTHON_DEPENDENCIES ${GTSAM_PYTHON_UNSTABLE_TARGET})
  143. endif()
  144. # Add custom target so we can install with `make python-install`
  145. set(GTSAM_PYTHON_INSTALL_TARGET python-install)
  146. add_custom_target(${GTSAM_PYTHON_INSTALL_TARGET}
  147. COMMAND ${PYTHON_EXECUTABLE} ${GTSAM_PYTHON_BUILD_DIRECTORY}/setup.py install
  148. DEPENDS ${GTSAM_PYTHON_DEPENDENCIES}
  149. WORKING_DIRECTORY ${GTSAM_PYTHON_BUILD_DIRECTORY})
  150. # Custom make command to run all GTSAM Python tests
  151. add_custom_target(
  152. python-test
  153. COMMAND
  154. ${CMAKE_COMMAND} -E env # add package to python path so no need to install
  155. "PYTHONPATH=${GTSAM_PYTHON_BUILD_DIRECTORY}/$ENV{PYTHONPATH}"
  156. ${PYTHON_EXECUTABLE} -m unittest discover -v -s .
  157. DEPENDS ${GTSAM_PYTHON_DEPENDENCIES}
  158. WORKING_DIRECTORY "${GTSAM_PYTHON_BUILD_DIRECTORY}/gtsam/tests")