otel-install-functions.cmake 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. # Copyright The OpenTelemetry Authors
  2. # SPDX-License-Identifier: Apache-2.0
  3. include("${PROJECT_SOURCE_DIR}/cmake/thirdparty-dependency-config.cmake")
  4. ########################################################################
  5. # INTERNAL FUNCTIONS - do not call directly. Use the otel_* "Main" functions
  6. ########################################################################
  7. #-----------------------------------------------------------------------
  8. # _otel_set_component_properties:
  9. # Sets the component properties used for install.
  10. # Properties set on PROJECT_SOURCE_DIR directory include:
  11. # OTEL_COMPONENTS_LIST: List of components added using otel_add_component
  12. # OTEL_COMPONENT_TARGETS_<component>: List of targets associated with the component
  13. # OTEL_COMPONENT_TARGETS_ALIAS_<component>: List of targets aliases associated with the component
  14. # OTEL_COMPONENT_FILES_DIRECTORY_<component>: Directory containing files to be installed with the component
  15. # OTEL_COMPONENT_FILES_DESTINATION_<component>: Destination directory for the files
  16. # OTEL_COMPONENT_FILES_MATCHING_<component>: Matching pattern for the files to be installed
  17. # OTEL_COMPONENT_DEPENDS_<component>: List of components that this component depends on
  18. # OTEL_COMPONENT_THIRDPARTY_DEPENDS_<component>: List of thirdparty dependencies that this component depends on
  19. #-----------------------------------------------------------------------
  20. function(_otel_set_component_properties)
  21. set(optionArgs )
  22. set(oneValueArgs COMPONENT FILES_DIRECTORY FILES_DESTINATION)
  23. set(multiValueArgs TARGETS TARGETS_ALIAS FILES_MATCHING COMPONENT_DEPENDS THIRDPARTY_DEPENDS)
  24. cmake_parse_arguments(_PROPERTIES "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
  25. # Add the component to the current components list
  26. get_property(existing_components DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENTS_LIST)
  27. if(_PROPERTIES_COMPONENT IN_LIST existing_components)
  28. message(FATAL_ERROR " component ${_PROPERTIES_COMPONENT} has already been created.")
  29. endif()
  30. list(APPEND existing_components "${_PROPERTIES_COMPONENT}")
  31. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENTS_LIST "${existing_components}")
  32. # Set the component targets property
  33. if(_PROPERTIES_TARGETS)
  34. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_TARGETS_${_PROPERTIES_COMPONENT} "${_PROPERTIES_TARGETS}")
  35. else()
  36. message(FATAL_ERROR " component ${_PROPERTIES_COMPONENT} does not have any targets.")
  37. endif()
  38. # Set the component targets alias property
  39. if(_PROPERTIES_TARGETS_ALIAS)
  40. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_TARGETS_ALIAS_${_PROPERTIES_COMPONENT} "${_PROPERTIES_TARGETS_ALIAS}")
  41. endif()
  42. # Set the component files property
  43. if(_PROPERTIES_FILES_DIRECTORY)
  44. if(NOT _PROPERTIES_FILES_DESTINATION)
  45. message(FATAL_ERROR " component ${_PROPERTIES_COMPONENT} has FILES_DIRECTORY set and must have FILES_DESINATION set.")
  46. endif()
  47. if(NOT _PROPERTIES_FILES_MATCHING)
  48. message(FATAL_ERROR " component ${_PROPERTIES_COMPONENT} has FILES_DIRECTORY set and must have FILES_MATCHING set.")
  49. endif()
  50. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_FILES_DIRECTORY_${_PROPERTIES_COMPONENT} "${_PROPERTIES_FILES_DIRECTORY}")
  51. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_FILES_DESTINATION_${_PROPERTIES_COMPONENT} "${_PROPERTIES_FILES_DESTINATION}")
  52. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_FILES_MATCHING_${_PROPERTIES_COMPONENT} "${_PROPERTIES_FILES_MATCHING}")
  53. endif()
  54. if(_PROPERTIES_COMPONENT_DEPENDS)
  55. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_DEPENDS_${_PROPERTIES_COMPONENT} "${_PROPERTIES_COMPONENT_DEPENDS}")
  56. endif()
  57. if(_PROPERTIES_THIRDPARTY_DEPENDS)
  58. set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_THIRDPARTY_DEPENDS_${_PROPERTIES_COMPONENT} "${_PROPERTIES_THIRDPARTY_DEPENDS}")
  59. endif()
  60. endfunction()
  61. #-----------------------------------------------------------------------
  62. # _otel_set_target_component_property:
  63. # Sets the target's INTERFACE_OTEL_COMPONENT_NAME property to the component.
  64. # A target can only be assigned to one component.
  65. # Note: The INTERFACE_* prefix can be dropped with CMake 3.19+ when custom
  66. # properties without the prefix are supported on INTERFACE targets.
  67. #-----------------------------------------------------------------------
  68. function(_otel_set_target_component_property _TARGET _COMPONENT)
  69. get_target_property(_TARGET_COMPONENT ${_TARGET} INTERFACE_OTEL_COMPONENT_NAME)
  70. if(_TARGET_COMPONENT)
  71. message(FATAL_ERROR " Target ${_TARGET} is already assigned to an opentelemetry-cpp COMPONENT ${_TARGET_COMPONENT}.")
  72. endif()
  73. set_target_properties(${_TARGET} PROPERTIES INTERFACE_OTEL_COMPONENT_NAME ${_OTEL_ADD_COMP_COMPONENT})
  74. endfunction()
  75. #-----------------------------------------------------------------------
  76. # _otel_append_dependent_components:
  77. # Appends the dependent component to the OUT_COMPONENTS variable.
  78. # The dependent component is defined in the OTEL_COMPONENT_DEPENDS_<component> property
  79. # on the PROJECT_SOURCE_DIR directory.
  80. #-----------------------------------------------------------------------
  81. function(_otel_append_dependent_components _COMPONENT OUT_COMPONENTS)
  82. get_property(_COMPONENT_DEPENDS DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_DEPENDS_${_COMPONENT})
  83. if(_COMPONENT_DEPENDS)
  84. set(_output_components "${${OUT_COMPONENTS}}")
  85. message(DEBUG " - adding dependent component ${_COMPONENT_DEPENDS} from component ${_COMPONENT}")
  86. list(APPEND _output_components ${_COMPONENT_DEPENDS})
  87. set(${OUT_COMPONENTS} "${_output_components}" PARENT_SCOPE)
  88. endif()
  89. endfunction()
  90. #-----------------------------------------------------------------------
  91. # _otel_append_component_found:
  92. # Checks if the target is associated with an otel component using the INTERFACE_OTEL_COMPONENT_NAME target property.
  93. # If so then the component is appended to the OUT_COMPONENTS varaiable.
  94. #-----------------------------------------------------------------------
  95. function(_otel_append_component_found _COMPONENT _TARGET OUT_COMPONENTS OUT_COMPONENT_FOUND)
  96. set(_output_components "${${OUT_COMPONENTS}}")
  97. get_target_property(_DEPEND_COMPONENT ${_TARGET} INTERFACE_OTEL_COMPONENT_NAME)
  98. if(_DEPEND_COMPONENT AND NOT ${_DEPEND_COMPONENT} STREQUAL ${_COMPONENT})
  99. _otel_append_dependent_components(${_DEPEND_COMPONENT} _output_components)
  100. message(DEBUG " - adding dependent component ${_DEPEND_COMPONENT} from target ${_TARGET}")
  101. list(APPEND _output_components ${_DEPEND_COMPONENT})
  102. set(${OUT_COMPONENT_FOUND} TRUE PARENT_SCOPE)
  103. else()
  104. set(${OUT_COMPONENT_FOUND} FALSE PARENT_SCOPE)
  105. endif()
  106. set(${OUT_COMPONENTS} "${_output_components}" PARENT_SCOPE)
  107. endfunction()
  108. #-----------------------------------------------------------------------
  109. # _otel_append_thirdparty_found:
  110. # Tries to match one of the supported third-party dependencies to the target name.
  111. # If found the dependency project name is appended to the OUT_THIRDPARTY_DEPS variable.
  112. # The match is based on the OTEL_THIRDPARTY_DEPENDENCIES_SUPPORTED list and optional
  113. # OTEL_<dependency>_TARGET_NAMESPACE variables.
  114. #------------------------------------------------------------------------
  115. function(_otel_append_thirdparty_found _TARGET OUT_THIRDPARTY_DEPS)
  116. set(_output_thirdparty_deps "${${OUT_THIRDPARTY_DEPS}}")
  117. foreach(_DEPENDENCY ${OTEL_THIRDPARTY_DEPENDENCIES_SUPPORTED})
  118. # Search for the dependency namespace in the target name
  119. if(NOT "${OTEL_${_DEPENDENCY}_TARGET_NAMESPACE}" STREQUAL "")
  120. set(_DEPENDENCY_NAMESPACE "${OTEL_${_DEPENDENCY}_TARGET_NAMESPACE}")
  121. else()
  122. set(_DEPENDENCY_NAMESPACE "${_DEPENDENCY}")
  123. endif()
  124. string(FIND "${_TARGET}" "${_DEPENDENCY_NAMESPACE}" _is_thirdparty)
  125. if(_is_thirdparty GREATER -1)
  126. message(DEBUG " - adding thirdparty dependency ${_DEPENDENCY} from target ${_TARGET}")
  127. list(APPEND _output_thirdparty_deps ${_DEPENDENCY})
  128. endif()
  129. endforeach()
  130. set(${OUT_THIRDPARTY_DEPS} "${_output_thirdparty_deps}" PARENT_SCOPE)
  131. endfunction()
  132. #-----------------------------------------------------------------------
  133. # _otel_collect_component_dependencies:
  134. # Collects the component to component dependencies and thirdparty dependencies of a target.
  135. # The dependencies are collected from the target's LINK_LIBRARIES property# and are appended
  136. # to the OUT_COMPONENT_DEPS and OUT_THIRDPARTY_DEPS variables.
  137. #------------------------------------------------------------------------
  138. function(_otel_collect_component_dependencies _TARGET _COMPONENT OUT_COMPONENT_DEPS OUT_THIRDPARTY_DEPS)
  139. get_target_property(_TARGET_TYPE ${_TARGET} TYPE)
  140. message(DEBUG " Target: ${_TARGET} - Type: ${_TARGET_TYPE}")
  141. # Set the linked libraries to search for dependencies
  142. set(_linked_libraries "")
  143. if(_TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
  144. get_target_property(_interface_libs ${_TARGET} INTERFACE_LINK_LIBRARIES)
  145. set(_linked_libraries "${_interface_libs}")
  146. message(DEBUG " - INTERFACE_LINK_LIBRARIES: ${_interface_libs}")
  147. else()
  148. get_target_property(_link_libs ${_TARGET} LINK_LIBRARIES)
  149. set(_linked_libraries "${_link_libs}")
  150. message(DEBUG " - LINK_LIBRARIES: ${_link_libs}")
  151. endif()
  152. set(_component_deps "${${OUT_COMPONENT_DEPS}}")
  153. set(_thirdparty_deps "${${OUT_THIRDPARTY_DEPS}}")
  154. foreach(_linked_target ${_linked_libraries})
  155. # Handle targets
  156. if(TARGET "${_linked_target}")
  157. set(_component_found FALSE)
  158. _otel_append_component_found(${_COMPONENT} "${_linked_target}" _component_deps _component_found)
  159. if(NOT ${_component_found})
  160. _otel_append_thirdparty_found(${_linked_target} _thirdparty_deps)
  161. endif()
  162. continue()
  163. endif()
  164. # Skip BUILD_INTERFACE targets
  165. string(FIND "${_linked_target}" "$<BUILD_INTERFACE:" _is_build_interface)
  166. if(_is_build_interface GREATER -1)
  167. message(DEBUG " - skipping BUILD_INTERFACE target: ${_linked_target}")
  168. continue()
  169. endif()
  170. # Handle targets in generator expressions
  171. string(FIND "${_linked_target}" "$<" _is_generator_expression)
  172. if(_is_generator_expression GREATER -1)
  173. # Find targets in generator expressions (there can be more than one per expression)
  174. string(REGEX MATCHALL "[A-Za-z0-9_\\-\\.]+(::[A-Za-z0-9_\\-\\.]+)*" _parsed_targets "${_linked_target}")
  175. foreach(_parsed_target ${_parsed_targets})
  176. if(TARGET ${_parsed_target})
  177. set(_component_found FALSE)
  178. _otel_append_component_found(${_COMPONENT} "${_parsed_target}" _component_deps _component_found)
  179. if(NOT ${_component_found})
  180. _otel_append_thirdparty_found(${_parsed_target} _thirdparty_deps)
  181. endif()
  182. endif()
  183. endforeach()
  184. endif()
  185. endforeach()
  186. list(REMOVE_DUPLICATES _component_deps)
  187. list(REMOVE_DUPLICATES _thirdparty_deps)
  188. set(${OUT_COMPONENT_DEPS} "${_component_deps}" PARENT_SCOPE)
  189. set(${OUT_THIRDPARTY_DEPS} "${_thirdparty_deps}" PARENT_SCOPE)
  190. endfunction()
  191. #-----------------------------------------------------------------------
  192. # _otel_add_target_alias:
  193. # Adds an alias target using target's export name and project name.
  194. # opentelemetry-cpp::<target_export_name>
  195. #------------------------------------------------------------------------
  196. function(_otel_add_target_alias _TARGET OUT_ALIAS_TARGETS)
  197. get_target_property(_TARGET_EXPORT_NAME ${_TARGET} EXPORT_NAME)
  198. if(NOT _TARGET_EXPORT_NAME)
  199. message(FATAL_ERROR " Target ${_TARGET} does not have an EXPORT_NAME property.")
  200. elseif(NOT TARGET "${PROJECT_NAME}::${_TARGET_EXPORT_NAME}")
  201. add_library("${PROJECT_NAME}::${_TARGET_EXPORT_NAME}" ALIAS ${_TARGET})
  202. endif()
  203. set(_alias_targets "${${OUT_ALIAS_TARGETS}}")
  204. list(APPEND _alias_targets "${PROJECT_NAME}::${_TARGET_EXPORT_NAME}")
  205. set(${OUT_ALIAS_TARGETS} "${_alias_targets}" PARENT_SCOPE)
  206. endfunction()
  207. #-----------------------------------------------------------------------
  208. # _otel_install_component:
  209. # Installs the component targets and optional files
  210. #-----------------------------------------------------------------------
  211. function(_otel_install_component _COMPONENT)
  212. install(
  213. TARGETS ${_COMPONENT_TARGETS}
  214. EXPORT "${PROJECT_NAME}-${_COMPONENT}-target"
  215. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  216. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  217. ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_COMPONENT})
  218. install(
  219. EXPORT "${PROJECT_NAME}-${_COMPONENT}-target"
  220. FILE "${PROJECT_NAME}-${_COMPONENT}-target.cmake"
  221. NAMESPACE "${PROJECT_NAME}::"
  222. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  223. COMPONENT ${_COMPONENT})
  224. if(_COMPONENT_FILES_DIRECTORY)
  225. install(
  226. DIRECTORY ${_COMPONENT_FILES_DIRECTORY}
  227. DESTINATION ${_COMPONENT_FILES_DESTINATION}
  228. COMPONENT ${_COMPONENT}
  229. FILES_MATCHING ${_COMPONENT_FILES_MATCHING})
  230. endif()
  231. endfunction()
  232. #-----------------------------------------------------------------------
  233. # _otel_populate_component_targets_block:
  234. # Populates the OTEL_COMPONENTS_TARGETS_BLOCK with the component targets
  235. # - sets COMPONENT_<component>_TARGETS variables
  236. #-----------------------------------------------------------------------
  237. function(_otel_populate_component_targets_block IN_COMPONENT COMPONENTS_TARGETS_BLOCK)
  238. # Populate OTEL_COMPONENTS_TARGETS_BLOCK
  239. set(_targets_block ${${COMPONENTS_TARGETS_BLOCK}})
  240. string(APPEND _targets_block
  241. "# COMPONENT ${IN_COMPONENT}\n"
  242. "set(COMPONENT_${IN_COMPONENT}_TARGETS\n"
  243. )
  244. foreach(_TARGET IN LISTS _COMPONENT_TARGETS_ALIAS)
  245. string(APPEND _targets_block " ${_TARGET}\n")
  246. endforeach()
  247. string(APPEND _targets_block ")\n\n")
  248. set(${COMPONENTS_TARGETS_BLOCK} "${_targets_block}" PARENT_SCOPE)
  249. endfunction()
  250. #-----------------------------------------------------------------------
  251. # _otel_populate_component_internal_depends_block:
  252. # Populates the OTEL_COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK with the component dependencies
  253. # - sets COMPONENT_<component>_COMPONENT_DEPENDS variables
  254. #-----------------------------------------------------------------------
  255. function(_otel_populate_component_internal_depends_block IN_COMPONENT COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK)
  256. # Populate OTEL_COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK
  257. set(_deps_block ${${COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK}})
  258. string(APPEND _deps_block
  259. "# COMPONENT ${IN_COMPONENT} internal dependencies\n"
  260. "set(COMPONENT_${IN_COMPONENT}_COMPONENT_DEPENDS\n"
  261. )
  262. foreach(dep IN LISTS _COMPONENT_DEPENDS)
  263. string(APPEND _deps_block " ${dep}\n")
  264. endforeach()
  265. string(APPEND _deps_block ")\n\n")
  266. set(${COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK} "${_deps_block}" PARENT_SCOPE)
  267. endfunction()
  268. #-----------------------------------------------------------------------
  269. function(_otel_populate_component_thirdparty_depends_block IN_COMPONENT COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK)
  270. # Populate OTEL_COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK
  271. set(_deps_block ${${COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK}})
  272. string(APPEND _deps_block
  273. "# COMPONENT ${IN_COMPONENT} thirdparty dependencies\n"
  274. "set(COMPONENT_${IN_COMPONENT}_THIRDPARTY_DEPENDS\n"
  275. )
  276. foreach(dep IN LISTS _COMPONENT_THIRDPARTY_DEPENDS)
  277. string(APPEND _deps_block " ${dep}\n")
  278. endforeach()
  279. string(APPEND _deps_block ")\n\n")
  280. set(${COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK} "${_deps_block}" PARENT_SCOPE)
  281. endfunction()
  282. #-----------------------------------------------------------------------
  283. ########################################################################
  284. # Main functions to support installing components
  285. # and the opentlemetry-cpp cmake package config files
  286. ########################################################################
  287. #-----------------------------------------------------------------------
  288. # otel_add_component:
  289. # Adds a component to the list of components to be installed. A component name and list of targest are required.
  290. # Optional files can be added to the component by specifying a directory, destination and matching pattern.
  291. # Each target is assigned to the component and its dependencies are identified based on the LINK_LIBRARIES property.
  292. # An alias target is also created for each target in the form of PROJECT_NAME::TARGET_EXPORT_NAME.
  293. # Usage:
  294. # otel_add_component(
  295. # COMPONENT <component_name>
  296. # TARGETS <target1> <target2> ...
  297. # FILES_DIRECTORY <directory>
  298. # FILES_DESTINATION <destination>
  299. # FILES_MATCHING <matching>)
  300. #-----------------------------------------------------------------------
  301. function(otel_add_component)
  302. set(optionArgs )
  303. set(oneValueArgs COMPONENT FILES_DIRECTORY FILES_DESTINATION)
  304. set(multiValueArgs TARGETS FILES_MATCHING)
  305. cmake_parse_arguments(_OTEL_ADD_COMP "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
  306. if(NOT _OTEL_ADD_COMP_COMPONENT)
  307. message(FATAL_ERROR "otel_add_component: COMPONENT is required")
  308. endif()
  309. if(NOT _OTEL_ADD_COMP_TARGETS)
  310. message(FATAL_ERROR "otel_add_component: TARGETS is required")
  311. endif()
  312. message(DEBUG "Add COMPONENT: ${_OTEL_ADD_COMP_COMPONENT}")
  313. set(_COMPONENT_DEPENDS "")
  314. set(_THIRDPARTY_DEPENDS "")
  315. set(_ALIAS_TARGETS "")
  316. foreach(_TARGET ${_OTEL_ADD_COMP_TARGETS})
  317. if(NOT TARGET ${_TARGET})
  318. message(FATAL_ERROR " Target ${_TARGET} not found")
  319. endif()
  320. _otel_set_target_component_property(${_TARGET} ${_OTEL_ADD_COMP_COMPONENT})
  321. _otel_collect_component_dependencies(${_TARGET} ${_OTEL_ADD_COMP_COMPONENT} _COMPONENT_DEPENDS _THIRDPARTY_DEPENDS)
  322. _otel_add_target_alias(${_TARGET} _ALIAS_TARGETS)
  323. endforeach()
  324. if(_OTEL_ADD_COMP_FILES_DIRECTORY)
  325. set(_OTEL_ADD_COMP_FILES_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${_OTEL_ADD_COMP_FILES_DIRECTORY}")
  326. endif()
  327. message(DEBUG " TARGETS: ${_OTEL_ADD_COMP_TARGETS}")
  328. message(DEBUG " TARGETS_ALIAS: ${_ALIAS_TARGETS}")
  329. message(DEBUG " COMPONENT_DEPENDS: ${_COMPONENT_DEPENDS}")
  330. message(DEBUG " THIRDPARTY_DEPENDS: ${_THIRDPARTY_DEPENDS}")
  331. message(DEBUG " FILES_DIRECTORY: ${_OTEL_ADD_COMP_FILES_DIRECTORY}")
  332. message(DEBUG " FILES_DESTINATION: ${_OTEL_ADD_COMP_FILES_DESTINATION}")
  333. message(DEBUG " FILES_MATCHING: ${_OTEL_ADD_COMP_FILES_MATCHING}")
  334. _otel_set_component_properties(
  335. COMPONENT ${_OTEL_ADD_COMP_COMPONENT}
  336. TARGETS ${_OTEL_ADD_COMP_TARGETS}
  337. TARGETS_ALIAS ${_ALIAS_TARGETS}
  338. FILES_DIRECTORY ${_OTEL_ADD_COMP_FILES_DIRECTORY}
  339. FILES_DESTINATION ${_OTEL_ADD_COMP_FILES_DESTINATION}
  340. FILES_MATCHING ${_OTEL_ADD_COMP_FILES_MATCHING}
  341. COMPONENT_DEPENDS ${_COMPONENT_DEPENDS}
  342. THIRDPARTY_DEPENDS ${_THIRDPARTY_DEPENDS})
  343. endfunction()
  344. #-----------------------------------------------------------------------
  345. # otel_install_components:
  346. # Installs all components that have been added using otel_add_component.
  347. # The components are installed in the order they were added.
  348. # The install function will create a cmake config file for each component
  349. # that contains the component name, targets, dependencies and thirdparty dependencies.
  350. # Usage:
  351. # otel_install_components()
  352. #-----------------------------------------------------------------------
  353. function(otel_install_components)
  354. get_property(OTEL_BUILT_COMPONENTS_LIST DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENTS_LIST)
  355. message(STATUS "Installing components:")
  356. set(OTEL_COMPONENTS_TARGETS_BLOCK "")
  357. set(OTEL_COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK "")
  358. set(OTEL_COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK "")
  359. foreach(_COMPONENT ${OTEL_BUILT_COMPONENTS_LIST})
  360. get_property(_COMPONENT_DEPENDS DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_DEPENDS_${_COMPONENT})
  361. get_property(_COMPONENT_TARGETS DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_TARGETS_${_COMPONENT})
  362. get_property(_COMPONENT_TARGETS_ALIAS DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_TARGETS_ALIAS_${_COMPONENT})
  363. get_property(_COMPONENT_THIRDPARTY_DEPENDS DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_THIRDPARTY_DEPENDS_${_COMPONENT})
  364. get_property(_COMPONENT_FILES_DIRECTORY DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_FILES_DIRECTORY_${_COMPONENT})
  365. get_property(_COMPONENT_FILES_DESTINATION DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_FILES_DESTINATION_${_COMPONENT})
  366. get_property(_COMPONENT_FILES_MATCHING DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY OTEL_COMPONENT_FILES_MATCHING_${_COMPONENT})
  367. message(STATUS "Install COMPONENT ${_COMPONENT}")
  368. message(STATUS " TARGETS: ${_COMPONENT_TARGETS}")
  369. message(STATUS " TARGETS_ALIAS: ${_COMPONENT_TARGETS_ALIAS}")
  370. message(STATUS " COMPONENT_DEPENDS: ${_COMPONENT_DEPENDS}")
  371. message(STATUS " THIRDPARTY_DEPENDS: ${_COMPONENT_THIRDPARTY_DEPENDS}")
  372. message(STATUS " FILES_DIRECTORY: ${_COMPONENT_FILES_DIRECTORY}")
  373. message(STATUS " FILES_DESTINATION: ${_COMPONENT_FILES_DESTINATION}")
  374. message(STATUS " FILES_MATCHING: ${_COMPONENT_FILES_MATCHING}")
  375. _otel_install_component(${_COMPONENT})
  376. _otel_populate_component_targets_block(${_COMPONENT} OTEL_COMPONENTS_TARGETS_BLOCK)
  377. _otel_populate_component_internal_depends_block(${_COMPONENT} OTEL_COMPONENTS_INTERNAL_DEPENDENCIES_BLOCK)
  378. _otel_populate_component_thirdparty_depends_block(${_COMPONENT} OTEL_COMPONENTS_THIRDPARTY_DEPENDENCIES_BLOCK)
  379. endforeach()
  380. configure_file(
  381. "${PROJECT_SOURCE_DIR}/cmake/templates/component-definitions.cmake.in"
  382. "${CMAKE_CURRENT_BINARY_DIR}/cmake/component-definitions.cmake"
  383. @ONLY
  384. )
  385. install(
  386. FILES
  387. "${CMAKE_CURRENT_BINARY_DIR}/cmake/component-definitions.cmake"
  388. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  389. COMPONENT cmake-config)
  390. endfunction()
  391. #-----------------------------------------------------------------------
  392. # otel_install_thirdparty_definitions:
  393. # Installs the thirdparty dependency definitions file that contains the list
  394. # of thirdparty dependencies their versions and cmake search modes.
  395. # - sets `OTEL_THIRDPARTY_DEPENDENCIES_SUPPORTED` to the list of dependencies
  396. # - sets `OTEL_<dependency>_VERSION` to the version used to build opentelemetry-cpp
  397. # - sets `OTEL_<dependency>_SEARCH_MODE` to the search mode required to find the dependency
  398. # Usage:
  399. # otel_install_thirdparty_definitions()
  400. #-----------------------------------------------------------------------
  401. function(otel_install_thirdparty_definitions)
  402. set(OTEL_THIRDPARTY_DEPENDENCY_VERSIONS_BLOCK "")
  403. set(OTEL_THIRDPARTY_DEPENDENCY_SEARCH_MODES_BLOCK "")
  404. # Populate OTEL_THIRDPARTY_DEPENDENCY_VERSIONS_BLOCK
  405. foreach(_DEPENDENCY ${OTEL_THIRDPARTY_DEPENDENCIES_SUPPORTED})
  406. string(APPEND OTEL_THIRDPARTY_DEPENDENCY_VERSIONS_BLOCK
  407. "set(OTEL_${_DEPENDENCY}_VERSION \"${${_DEPENDENCY}_VERSION}\")\n"
  408. )
  409. endforeach()
  410. # Populate OTEL_THIRDPARTY_DEPENDENCY_SEARCH_MODES_BLOCK
  411. foreach(_DEPENDENCY ${OTEL_THIRDPARTY_DEPENDENCIES_SUPPORTED})
  412. string(APPEND OTEL_THIRDPARTY_DEPENDENCY_SEARCH_MODES_BLOCK
  413. "set(OTEL_${_DEPENDENCY}_SEARCH_MODE \"${OTEL_${_DEPENDENCY}_SEARCH_MODE}\")\n"
  414. )
  415. endforeach()
  416. configure_file(
  417. "${PROJECT_SOURCE_DIR}/cmake/templates/thirdparty-dependency-definitions.cmake.in"
  418. "${CMAKE_CURRENT_BINARY_DIR}/cmake/thirdparty-dependency-definitions.cmake"
  419. @ONLY)
  420. install(
  421. FILES
  422. "${CMAKE_CURRENT_BINARY_DIR}/cmake/thirdparty-dependency-definitions.cmake"
  423. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  424. COMPONENT cmake-config)
  425. endfunction()
  426. #-----------------------------------------------------------------------
  427. # otel_install_cmake_config:
  428. # Configures and installs the cmake.config package file and version file
  429. # to support find_package(opentelemetry-cpp CONFIG COMPONENTS ...)
  430. # Usage:
  431. # otel_install_cmake_config()
  432. #-----------------------------------------------------------------------
  433. function(otel_install_cmake_config)
  434. # Write config file for find_package(opentelemetry-cpp CONFIG)
  435. set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}")
  436. configure_package_config_file(
  437. "${PROJECT_SOURCE_DIR}/cmake/templates/opentelemetry-cpp-config.cmake.in"
  438. "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake"
  439. INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  440. PATH_VARS OPENTELEMETRY_ABI_VERSION_NO OPENTELEMETRY_VERSION PROJECT_NAME
  441. INCLUDE_INSTALL_DIR CMAKE_INSTALL_LIBDIR)
  442. # Write version file for find_package(opentelemetry-cpp CONFIG)
  443. write_basic_package_version_file(
  444. "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config-version.cmake"
  445. VERSION ${OPENTELEMETRY_VERSION}
  446. COMPATIBILITY ExactVersion)
  447. install(
  448. FILES
  449. "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake"
  450. "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config-version.cmake"
  451. "${CMAKE_CURRENT_LIST_DIR}/cmake/find-package-support-functions.cmake"
  452. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  453. COMPONENT cmake-config)
  454. endfunction()