CMakeLists.txt 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. # Copyright The OpenTelemetry Authors
  2. # SPDX-License-Identifier: Apache-2.0
  3. cmake_minimum_required(VERSION 3.14)
  4. # See https://cmake.org/cmake/help/latest/policy/CMP0074.html required by
  5. # certain version of zlib which CURL depends on.
  6. if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12")
  7. cmake_policy(SET CMP0074 NEW)
  8. endif()
  9. # Allow to use normal variable for option()
  10. if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13")
  11. cmake_policy(SET CMP0077 NEW)
  12. endif()
  13. # Prefer CMAKE_MSVC_RUNTIME_LIBRARY if possible
  14. if(POLICY CMP0091)
  15. cmake_policy(SET CMP0091 NEW)
  16. endif()
  17. if(POLICY CMP0092)
  18. # https://cmake.org/cmake/help/latest/policy/CMP0092.html#policy:CMP0092 Make
  19. # sure the /W3 is not removed from CMAKE_CXX_FLAGS since CMake 3.15
  20. cmake_policy(SET CMP0092 OLD)
  21. endif()
  22. # MSVC RTTI flag /GR should not be not added to CMAKE_CXX_FLAGS by default. @see
  23. # https://cmake.org/cmake/help/latest/policy/CMP0117.html
  24. if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.20.0")
  25. cmake_policy(SET CMP0117 NEW)
  26. endif()
  27. project(opentelemetry-cpp)
  28. # Mark variables as used so cmake doesn't complain about them
  29. mark_as_advanced(CMAKE_TOOLCHAIN_FILE)
  30. # Note: CMAKE_FIND_PACKAGE_PREFER_CONFIG requires cmake 3.15. Prefer cmake
  31. # CONFIG search mode to find dependencies. This is important to properly find
  32. # protobuf versions 3.22.0 and above due to the abseil-cpp dependency.
  33. set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
  34. # Don't use customized cmake modules if vcpkg is used to resolve dependence.
  35. if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
  36. list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")
  37. endif()
  38. if(EXISTS "${CMAKE_SOURCE_DIR}/third_party_release")
  39. file(STRINGS "${CMAKE_SOURCE_DIR}/third_party_release" third_party_tags)
  40. foreach(third_party ${third_party_tags})
  41. string(REGEX REPLACE "^[ ]+" "" third_party ${third_party})
  42. string(REGEX MATCH "^[^=]+" third_party_name ${third_party})
  43. string(REPLACE "${third_party_name}=" "" third_party_tag ${third_party})
  44. set(${third_party_name} "${third_party_tag}")
  45. endforeach()
  46. endif()
  47. if(DEFINED ENV{ARCH})
  48. # Architecture may be specified via ARCH environment variable
  49. set(ARCH $ENV{ARCH})
  50. else()
  51. # Autodetection logic that populates ARCH variable
  52. if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
  53. # Windows may report AMD64 even if target is 32-bit
  54. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  55. set(ARCH x64)
  56. elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
  57. set(ARCH x86)
  58. endif()
  59. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*")
  60. # Windows may report x86 even if target is 64-bit
  61. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  62. set(ARCH x64)
  63. elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
  64. set(ARCH x86)
  65. endif()
  66. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "powerpc")
  67. # AIX will report the processor as 'powerpc' even if building in 64-bit mode
  68. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  69. set(ARCH ppc64)
  70. else()
  71. set(ARCH ppc32)
  72. endif()
  73. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES
  74. "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)")
  75. set(ARCH arm64)
  76. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
  77. set(ARCH arm)
  78. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
  79. set(ARCH ppc64le)
  80. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
  81. set(ARCH ppc64)
  82. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)")
  83. set(ARCH mips)
  84. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(riscv.*|RISCV.*)")
  85. set(ARCH riscv)
  86. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x.*|S390X.*)")
  87. set(ARCH s390x)
  88. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(sparc.*|SPARC.*)")
  89. set(ARCH sparc)
  90. elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(loongarch.*|LOONGARCH.*)")
  91. set(ARCH loongarch)
  92. else()
  93. message(
  94. FATAL_ERROR
  95. "opentelemetry-cpp: unrecognized target processor ${CMAKE_SYSTEM_PROCESSOR} configuration!"
  96. )
  97. endif()
  98. endif()
  99. message(STATUS "Building for architecture ARCH=${ARCH}")
  100. # Autodetect vcpkg toolchain
  101. if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
  102. set(CMAKE_TOOLCHAIN_FILE
  103. "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
  104. CACHE STRING "")
  105. endif()
  106. if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
  107. include("${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
  108. endif()
  109. option(WITH_ABI_VERSION_1 "ABI version 1" ON)
  110. option(WITH_ABI_VERSION_2 "EXPERIMENTAL: ABI version 2 preview" OFF)
  111. file(READ "${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h"
  112. OPENTELEMETRY_CPP_HEADER_VERSION_H)
  113. #
  114. # We do not want to have WITH_ABI_VERSION = "1" or "2", and instead prefer two
  115. # distinct flags, WITH_ABI_VERSION_1 and WITH_ABI_VERSION_2.
  116. #
  117. # This allows:
  118. #
  119. # * to have a specific option description for each ABI
  120. # * to mark experimental/stable/deprecated on flags, for clarity
  121. # * to search for exact abi usage move easily, discouraging:
  122. #
  123. # * cmake -DWITH_ABI_VERSION=${ARG}
  124. #
  125. # While not supported, having distinct WITH_ABI_VERSION_1 and WITH_ABI_VERSION_2
  126. # flags also opens the possibility to support multiple ABI concurrently, should
  127. # that become necessary.
  128. #
  129. if(WITH_ABI_VERSION_1 AND WITH_ABI_VERSION_2)
  130. #
  131. # Only one ABI is supported in a build.
  132. #
  133. message(
  134. FATAL_ERROR "Set either WITH_ABI_VERSION_1 or WITH_ABI_VERSION_2, not both")
  135. endif()
  136. if(WITH_ABI_VERSION_2)
  137. set(OPENTELEMETRY_ABI_VERSION_NO "2")
  138. elseif(WITH_ABI_VERSION_1)
  139. set(OPENTELEMETRY_ABI_VERSION_NO "1")
  140. else()
  141. if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES
  142. "OPENTELEMETRY_ABI_VERSION_NO[ \t\r\n]+\"?([0-9]+)\"?")
  143. math(EXPR OPENTELEMETRY_ABI_VERSION_NO ${CMAKE_MATCH_1})
  144. else()
  145. message(
  146. FATAL_ERROR
  147. "OPENTELEMETRY_ABI_VERSION_NO not found on ${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h"
  148. )
  149. endif()
  150. endif()
  151. message(STATUS "OPENTELEMETRY_ABI_VERSION_NO=${OPENTELEMETRY_ABI_VERSION_NO}")
  152. if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES
  153. "OPENTELEMETRY_VERSION[ \t\r\n]+\"?([^\"]+)\"?")
  154. set(OPENTELEMETRY_VERSION ${CMAKE_MATCH_1})
  155. else()
  156. message(
  157. FATAL_ERROR
  158. "OPENTELEMETRY_VERSION not found on ${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h"
  159. )
  160. endif()
  161. message(STATUS "OPENTELEMETRY_VERSION=${OPENTELEMETRY_VERSION}")
  162. option(WITH_NO_DEPRECATED_CODE "Do not include deprecated code" OFF)
  163. set(WITH_STL
  164. "OFF"
  165. CACHE STRING "Which version of the Standard Library for C++ to use")
  166. option(WITH_GSL
  167. "Whether to use Guidelines Support Library for C++ latest features" OFF)
  168. set(OPENTELEMETRY_INSTALL_default ON)
  169. if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
  170. set(OPENTELEMETRY_INSTALL_default OFF)
  171. endif()
  172. option(OPENTELEMETRY_INSTALL "Whether to install opentelemetry targets"
  173. ${OPENTELEMETRY_INSTALL_default})
  174. include("${PROJECT_SOURCE_DIR}/cmake/tools.cmake")
  175. if(NOT WITH_STL STREQUAL "OFF")
  176. # These definitions are needed for test projects that do not link against
  177. # opentelemetry-api library directly. We ensure that variant implementation
  178. # (absl::variant or std::variant) in variant unit test code is consistent with
  179. # the global project build definitions. Optimize for speed to reduce the hops
  180. if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  181. if(CMAKE_BUILD_TYPE MATCHES Debug)
  182. # Turn off optimizations for DEBUG
  183. set(MSVC_CXX_OPT_FLAG "/Od")
  184. else()
  185. string(REGEX MATCH "\/O" result ${CMAKE_CXX_FLAGS})
  186. if(NOT ${result} MATCHES "\/O")
  187. set(MSVC_CXX_OPT_FLAG "/O2")
  188. endif()
  189. endif()
  190. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MSVC_CXX_OPT_FLAG}")
  191. endif()
  192. endif()
  193. option(WITH_OTLP_RETRY_PREVIEW
  194. "Whether to enable experimental retry functionality" OFF)
  195. option(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW
  196. "Whether to enable mTLS support fro gRPC" OFF)
  197. option(WITH_OTLP_GRPC "Whether to include the OTLP gRPC exporter in the SDK"
  198. OFF)
  199. option(WITH_OTLP_HTTP "Whether to include the OTLP http exporter in the SDK"
  200. OFF)
  201. option(WITH_OTLP_FILE "Whether to include the OTLP file exporter in the SDK"
  202. OFF)
  203. option(
  204. WITH_OTLP_HTTP_COMPRESSION
  205. "Whether to include gzip compression for the OTLP http exporter in the SDK"
  206. OFF)
  207. option(WITH_CURL_LOGGING "Whether to enable select CURL verbosity in OTel logs"
  208. OFF)
  209. option(WITH_ZIPKIN "Whether to include the Zipkin exporter in the SDK" OFF)
  210. option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK"
  211. OFF)
  212. option(WITH_ELASTICSEARCH
  213. "Whether to include the Elasticsearch Client in the SDK" OFF)
  214. option(WITH_NO_GETENV "Whether the platform supports environment variables" OFF)
  215. option(BUILD_TESTING "Whether to enable tests" ON)
  216. option(WITH_BENCHMARK "Whether to build benchmark program" ON)
  217. option(BUILD_W3CTRACECONTEXT_TEST "Whether to build w3c trace context" OFF)
  218. option(OTELCPP_MAINTAINER_MODE "Build in maintainer mode (-Wall -Werror)" OFF)
  219. option(WITH_OPENTRACING "Whether to include the Opentracing shim" OFF)
  220. option(OTELCPP_VERSIONED_LIBS "Whether to generate the versioned shared libs"
  221. OFF)
  222. #
  223. # This option is experimental, subject to change in the spec:
  224. #
  225. # * https://github.com/open-telemetry/opentelemetry-specification/issues/2232
  226. #
  227. option(WITH_REMOVE_METER_PREVIEW
  228. "EXPERIMENTAL, ABI BREAKING: Allow to remove a meter" OFF)
  229. if(OTELCPP_VERSIONED_LIBS AND NOT BUILD_SHARED_LIBS)
  230. message(FATAL_ERROR "OTELCPP_VERSIONED_LIBS=ON requires BUILD_SHARED_LIBS=ON")
  231. endif()
  232. if(WIN32)
  233. option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON)
  234. else()
  235. if(DEFINED (WITH_ETW))
  236. message(FATAL_ERROR "WITH_ETW is only supported on Windows")
  237. endif()
  238. endif(WIN32)
  239. # Do not convert deprecated message to error
  240. if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
  241. add_compile_options(-Wno-error=deprecated-declarations)
  242. endif()
  243. option(
  244. WITH_API_ONLY
  245. "Only build the API (use as a header-only library). Overrides WITH_EXAMPLES and all options to enable exporters"
  246. OFF)
  247. option(WITH_EXAMPLES "Whether to build examples" ON)
  248. # This requires CURL, OFF by default.
  249. option(
  250. WITH_EXAMPLES_HTTP
  251. "Whether to build http client/server examples. Requires WITH_EXAMPLES and CURL"
  252. OFF)
  253. option(WITH_FUNC_TESTS "Whether to build functional tests" ON)
  254. option(WITH_ASYNC_EXPORT_PREVIEW "Whether to enable async export" OFF)
  255. # Exemplar specs status is experimental, so behind feature flag by default
  256. option(WITH_METRICS_EXEMPLAR_PREVIEW
  257. "Whether to enable exemplar within metrics" OFF)
  258. # Experimental, so behind feature flag by default
  259. option(WITH_THREAD_INSTRUMENTATION_PREVIEW
  260. "Whether to enable thread instrumentation" OFF)
  261. option(OPENTELEMETRY_SKIP_DYNAMIC_LOADING_TESTS
  262. "Whether to build test libraries that are always linked as shared libs"
  263. OFF)
  264. #
  265. # Verify options dependencies
  266. #
  267. if(WITH_EXAMPLES_HTTP AND NOT WITH_EXAMPLES)
  268. message(FATAL_ERROR "WITH_EXAMPLES_HTTP=ON requires WITH_EXAMPLES=ON")
  269. endif()
  270. find_package(Threads)
  271. function(install_windows_deps)
  272. # Bootstrap vcpkg from CMake and auto-install deps in case if we are missing
  273. # deps on Windows. Respect the target architecture variable.
  274. set(VCPKG_TARGET_ARCHITECTURE
  275. ${ARCH}
  276. PARENT_SCOPE)
  277. message(STATUS "Installing build tools and dependencies...")
  278. set(ENV{ARCH} ${ARCH})
  279. execute_process(
  280. COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/setup-buildtools.cmd)
  281. set(CMAKE_TOOLCHAIN_FILE
  282. ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake
  283. CACHE FILEPATH "")
  284. message(
  285. STATUS
  286. "Make sure that vcpkg.cmake is set as the CMAKE_TOOLCHAIN_FILE at the START of the cmake build process!
  287. Can be command-line arg (cmake -DCMAKE_TOOLCHAIN_FILE=...) or set in your editor of choice."
  288. )
  289. endfunction()
  290. function(set_target_version target_name)
  291. if(OTELCPP_VERSIONED_LIBS)
  292. set_target_properties(
  293. ${target_name} PROPERTIES VERSION ${OPENTELEMETRY_VERSION}
  294. SOVERSION ${OPENTELEMETRY_ABI_VERSION_NO})
  295. endif()
  296. endfunction()
  297. if(MSVC)
  298. # Options for Visual C++ compiler: /Zc:__cplusplus - report an updated value
  299. # for recent C++ language standards. Without this option MSVC returns the
  300. # value of __cplusplus="199711L"
  301. if(MSVC_VERSION GREATER 1900)
  302. # __cplusplus flag is not supported by Visual Studio 2015
  303. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus")
  304. endif()
  305. endif()
  306. # include GNUInstallDirs before include cmake/opentelemetry-proto.cmake because
  307. # opentelemetry-proto installs targets to the location variables defined in
  308. # GNUInstallDirs.
  309. include(GNUInstallDirs)
  310. if(WITH_PROMETHEUS)
  311. find_package(prometheus-cpp CONFIG QUIET)
  312. if(NOT prometheus-cpp_FOUND)
  313. message(STATUS "Trying to use local prometheus-cpp from submodule")
  314. if(EXISTS ${PROJECT_SOURCE_DIR}/third_party/prometheus-cpp/.git)
  315. set(SAVED_ENABLE_TESTING ${ENABLE_TESTING})
  316. set(SAVED_CMAKE_CXX_CLANG_TIDY ${CMAKE_CXX_CLANG_TIDY})
  317. set(SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE
  318. ${CMAKE_CXX_INCLUDE_WHAT_YOU_USE})
  319. set(ENABLE_TESTING OFF)
  320. set(CMAKE_CXX_CLANG_TIDY "")
  321. set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "")
  322. add_subdirectory(third_party/prometheus-cpp)
  323. set(ENABLE_TESTING ${SAVED_ENABLE_TESTING})
  324. set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY})
  325. set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE
  326. ${SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE})
  327. # Get the version of the prometheus-cpp submodule
  328. find_package(Git QUIET)
  329. if(Git_FOUND)
  330. execute_process(
  331. COMMAND ${GIT_EXECUTABLE} describe --tags --always
  332. WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/third_party/prometheus-cpp
  333. OUTPUT_VARIABLE prometheus-cpp_VERSION
  334. OUTPUT_STRIP_TRAILING_WHITESPACE)
  335. string(REGEX REPLACE "^v" "" prometheus-cpp_VERSION
  336. "${prometheus-cpp_VERSION}")
  337. endif()
  338. message(
  339. STATUS
  340. "Using local prometheus-cpp from submodule. Version = ${prometheus-cpp_VERSION}"
  341. )
  342. else()
  343. message(
  344. FATAL_ERROR
  345. "\nprometheus-cpp package was not found. Please either provide it manually or clone with submodules. "
  346. "To initialize, fetch and checkout any nested submodules, you can use the following command:\n"
  347. "git submodule update --init --recursive")
  348. endif()
  349. else()
  350. message(STATUS "Using external prometheus-cpp")
  351. endif()
  352. endif()
  353. if(WITH_OTLP_GRPC
  354. OR WITH_OTLP_HTTP
  355. OR WITH_OTLP_FILE)
  356. # Including the CMakeFindDependencyMacro resolves an error from
  357. # gRPCConfig.cmake on some grpc versions. See
  358. # https://github.com/grpc/grpc/pull/33361 for more details.
  359. include(CMakeFindDependencyMacro)
  360. # Protobuf 3.22+ depends on abseil-cpp and must be found using the cmake
  361. # find_package CONFIG search mode. The following attempts to find Protobuf
  362. # using the CONFIG mode first, and if not found, falls back to the MODULE
  363. # mode. See https://gitlab.kitware.com/cmake/cmake/-/issues/24321 for more
  364. # details.
  365. find_package(Protobuf CONFIG)
  366. if(NOT Protobuf_FOUND)
  367. find_package(Protobuf MODULE)
  368. if(Protobuf_FOUND AND Protobuf_VERSION VERSION_GREATER_EQUAL "3.22.0")
  369. message(
  370. WARNING
  371. "Found Protobuf version ${Protobuf_VERSION} using MODULE mode. "
  372. "Linking errors may occur. Protobuf 3.22+ depends on abseil-cpp "
  373. "and should be found using the CONFIG mode.")
  374. endif()
  375. endif()
  376. if(WITH_OTLP_GRPC)
  377. find_package(gRPC CONFIG)
  378. endif()
  379. if((NOT Protobuf_FOUND) OR (WITH_OTLP_GRPC AND NOT gRPC_FOUND))
  380. if(WIN32 AND (NOT DEFINED CMAKE_TOOLCHAIN_FILE))
  381. install_windows_deps()
  382. endif()
  383. if(WIN32 AND (NOT DEFINED CMAKE_TOOLCHAIN_FILE))
  384. message(FATAL_ERROR "Windows dependency installation failed!")
  385. endif()
  386. if(WIN32)
  387. include(${CMAKE_TOOLCHAIN_FILE})
  388. endif()
  389. if(NOT Protobuf_FOUND)
  390. find_package(Protobuf CONFIG REQUIRED)
  391. endif()
  392. if(NOT gRPC_FOUND AND WITH_OTLP_GRPC)
  393. find_package(gRPC CONFIG)
  394. endif()
  395. if(WIN32)
  396. # Always use x64 protoc.exe
  397. if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
  398. set(Protobuf_PROTOC_EXECUTABLE
  399. ${CMAKE_CURRENT_SOURCE_DIR}/tools/vcpkg/packages/protobuf_x64-windows/tools/protobuf/protoc.exe
  400. )
  401. endif()
  402. endif()
  403. endif()
  404. # Latest Protobuf imported targets and without legacy module support
  405. if(TARGET protobuf::protoc)
  406. if(CMAKE_CROSSCOMPILING AND Protobuf_PROTOC_EXECUTABLE)
  407. set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
  408. else()
  409. project_build_tools_get_imported_location(PROTOBUF_PROTOC_EXECUTABLE
  410. protobuf::protoc)
  411. # If protobuf::protoc is not a imported target, then we use the target
  412. # directly for fallback
  413. if(NOT PROTOBUF_PROTOC_EXECUTABLE)
  414. set(PROTOBUF_PROTOC_EXECUTABLE protobuf::protoc)
  415. endif()
  416. endif()
  417. elseif(Protobuf_PROTOC_EXECUTABLE)
  418. # Some versions of FindProtobuf.cmake uses mixed case instead of uppercase
  419. set(PROTOBUF_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
  420. endif()
  421. include(CMakeDependentOption)
  422. message(STATUS "PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}")
  423. set(SAVED_CMAKE_CXX_CLANG_TIDY ${CMAKE_CXX_CLANG_TIDY})
  424. set(CMAKE_CXX_CLANG_TIDY "")
  425. include(cmake/opentelemetry-proto.cmake)
  426. set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY})
  427. endif()
  428. #
  429. # Do we need HTTP CLIENT CURL ?
  430. #
  431. if(WITH_OTLP_HTTP
  432. OR WITH_ELASTICSEARCH
  433. OR WITH_ZIPKIN
  434. OR BUILD_W3CTRACECONTEXT_TEST
  435. OR WITH_EXAMPLES_HTTP)
  436. set(WITH_HTTP_CLIENT_CURL ON)
  437. else()
  438. set(WITH_HTTP_CLIENT_CURL OFF)
  439. endif()
  440. #
  441. # Do we need CURL ?
  442. #
  443. if((NOT WITH_API_ONLY) AND WITH_HTTP_CLIENT_CURL)
  444. # No specific version required.
  445. find_package(CURL REQUIRED)
  446. # Set the CURL_VERSION from the legacy CURL_VERSION_STRING Required for CMake
  447. # versions below 4.0
  448. if(NOT DEFINED CURL_VERSION AND DEFINED CURL_VERSION_STRING)
  449. set(CURL_VERSION ${CURL_VERSION_STRING})
  450. endif()
  451. endif()
  452. #
  453. # Do we need ZLIB ?
  454. #
  455. if((NOT WITH_API_ONLY)
  456. AND WITH_HTTP_CLIENT_CURL
  457. AND WITH_OTLP_HTTP_COMPRESSION)
  458. # No specific version required.
  459. find_package(ZLIB REQUIRED)
  460. # Set the ZLIB_VERSION from the legacy ZLIB_VERSION_STRING Required for CMake
  461. # versions below 3.26
  462. if(NOT DEFINED ZLIB_VERSION AND DEFINED ZLIB_VERSION_STRING)
  463. set(ZLIB_VERSION ${ZLIB_VERSION_STRING})
  464. endif()
  465. endif()
  466. #
  467. # Do we need NLOHMANN_JSON ?
  468. #
  469. if(WITH_ELASTICSEARCH
  470. OR WITH_ZIPKIN
  471. OR WITH_OTLP_HTTP
  472. OR WITH_OTLP_FILE
  473. OR BUILD_W3CTRACECONTEXT_TEST
  474. OR WITH_ETW)
  475. set(USE_NLOHMANN_JSON ON)
  476. else()
  477. set(USE_NLOHMANN_JSON OFF)
  478. endif()
  479. if((NOT WITH_API_ONLY) AND USE_NLOHMANN_JSON)
  480. include(cmake/nlohmann-json.cmake)
  481. endif()
  482. if(OTELCPP_MAINTAINER_MODE)
  483. if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  484. message(STATUS "Building with gcc in maintainer mode.")
  485. add_compile_options(-Wall)
  486. add_compile_options(-Werror)
  487. add_compile_options(-Wextra)
  488. # Tested with GCC 9.4 on github.
  489. if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.4)
  490. message(STATUS "Building with additional warnings for gcc.")
  491. # Relaxed warnings
  492. # Enforced warnings
  493. # C++ options only
  494. add_compile_options($<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Wextra-semi>)
  495. add_compile_options(
  496. $<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Woverloaded-virtual>)
  497. add_compile_options(
  498. $<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Wsuggest-override>)
  499. add_compile_options(
  500. $<$<STREQUAL:$<COMPILE_LANGUAGE>,CXX>:-Wold-style-cast>)
  501. # C and C++
  502. add_compile_options(-Wcast-qual)
  503. add_compile_options(-Wformat-security)
  504. add_compile_options(-Wlogical-op)
  505. add_compile_options(-Wmissing-include-dirs)
  506. add_compile_options(-Wstringop-truncation)
  507. add_compile_options(-Wundef)
  508. add_compile_options(-Wvla)
  509. endif()
  510. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  511. message(STATUS "Building with clang in maintainer mode.")
  512. add_compile_options(-Wall)
  513. add_compile_options(-Werror)
  514. add_compile_options(-Wextra)
  515. # Tested with Clang 11.0 on github.
  516. if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0)
  517. message(STATUS "Building with additional warnings for clang.")
  518. # Relaxed warnings
  519. add_compile_options(-Wno-error=unused-private-field)
  520. # Enforced warnings
  521. add_compile_options(-Wcast-qual)
  522. add_compile_options(-Wconditional-uninitialized)
  523. add_compile_options(-Wextra-semi)
  524. add_compile_options(-Wformat-security)
  525. add_compile_options(-Wheader-hygiene)
  526. add_compile_options(-Winconsistent-missing-destructor-override)
  527. add_compile_options(-Winconsistent-missing-override)
  528. add_compile_options(-Wnewline-eof)
  529. add_compile_options(-Wnon-virtual-dtor)
  530. add_compile_options(-Woverloaded-virtual)
  531. add_compile_options(-Wrange-loop-analysis)
  532. add_compile_options(-Wundef)
  533. add_compile_options(-Wundefined-reinterpret-cast)
  534. add_compile_options(-Wvla)
  535. add_compile_options(-Wold-style-cast)
  536. endif()
  537. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  538. message(STATUS "Building with msvc in maintainer mode.")
  539. add_compile_options(/WX)
  540. add_compile_options(/W4)
  541. # Relaxed warnings
  542. add_compile_options(/wd4100)
  543. add_compile_options(/wd4125)
  544. add_compile_options(/wd4566)
  545. add_compile_options(/wd4127)
  546. add_compile_options(/wd4512)
  547. add_compile_options(/wd4267)
  548. add_compile_options(/wd4996)
  549. # Enforced warnings
  550. add_compile_options(/we4265) # 'class': class has virtual functions, but
  551. # destructor is not virtual
  552. add_compile_options(/we5204) # A class with virtual functions has
  553. # non-virtual trivial destructor.
  554. elseif()
  555. message(FATAL_ERROR "Building with unknown compiler in maintainer mode.")
  556. endif()
  557. endif(OTELCPP_MAINTAINER_MODE)
  558. list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
  559. include(CTest)
  560. if(BUILD_TESTING)
  561. if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a)
  562. # Prefer GTest from build tree. GTest is not always working with
  563. # CMAKE_PREFIX_PATH
  564. set(GTEST_INCLUDE_DIRS
  565. ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include
  566. ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include)
  567. if(TARGET gtest)
  568. set(GTEST_BOTH_LIBRARIES gtest gtest_main)
  569. else()
  570. set(GTEST_BOTH_LIBRARIES ${CMAKE_BINARY_DIR}/lib/libgtest.a
  571. ${CMAKE_BINARY_DIR}/lib/libgtest_main.a)
  572. endif()
  573. elseif(WIN32)
  574. # Make sure we are always bootsrapped with vcpkg on Windows
  575. find_package(GTest)
  576. if(NOT (GTEST_FOUND OR GTest_FOUND))
  577. if(DEFINED CMAKE_TOOLCHAIN_FILE)
  578. message(
  579. FATAL_ERROR
  580. "Pleaes install GTest with the CMAKE_TOOLCHAIN_FILE at ${CMAKE_TOOLCHAIN_FILE}"
  581. )
  582. else()
  583. install_windows_deps()
  584. include(${CMAKE_TOOLCHAIN_FILE})
  585. find_package(GTest REQUIRED)
  586. endif()
  587. endif()
  588. else()
  589. # Prefer GTest installed by OS distro, brew or vcpkg package manager
  590. find_package(GTest REQUIRED)
  591. endif()
  592. if(NOT GTEST_BOTH_LIBRARIES)
  593. # New GTest package names
  594. if(TARGET GTest::gtest)
  595. set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main)
  596. elseif(TARGET GTest::GTest)
  597. set(GTEST_BOTH_LIBRARIES GTest::GTest GTest::Main)
  598. endif()
  599. endif()
  600. if(GTEST_INCLUDE_DIRS)
  601. include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
  602. endif()
  603. message(STATUS "GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}")
  604. message(STATUS "GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}")
  605. # Try to find gmock
  606. if(NOT GMOCK_LIB AND TARGET GTest::gmock)
  607. set(GMOCK_LIB GTest::gmock)
  608. elseif(MSVC)
  609. # Explicitly specify that we consume GTest from shared library. The rest of
  610. # code logic below determines whether we link Release or Debug flavor of the
  611. # library. These flavors have different prefix on Windows, gmock and gmockd
  612. # respectively.
  613. add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1)
  614. if(GMOCK_LIB)
  615. # unset GMOCK_LIB to force find_library to redo the lookup, as the cached
  616. # entry could cause linking to incorrect flavor of gmock and leading to
  617. # runtime error.
  618. unset(GMOCK_LIB CACHE)
  619. endif()
  620. endif()
  621. if(NOT GMOCK_LIB)
  622. if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug")
  623. find_library(GMOCK_LIB gmockd PATH_SUFFIXES lib)
  624. else()
  625. find_library(GMOCK_LIB gmock PATH_SUFFIXES lib)
  626. endif()
  627. # Reset GMOCK_LIB if it was not found, or some target may link
  628. # GMOCK_LIB-NOTFOUND
  629. if(NOT GMOCK_LIB)
  630. unset(GMOCK_LIB)
  631. unset(GMOCK_LIB CACHE)
  632. endif()
  633. endif()
  634. enable_testing()
  635. if(WITH_BENCHMARK)
  636. # Benchmark respects the CMAKE_PREFIX_PATH
  637. find_package(benchmark CONFIG REQUIRED)
  638. endif()
  639. endif()
  640. # Record build config and versions
  641. message(STATUS "---------------------------------------------")
  642. message(STATUS "build settings")
  643. message(STATUS "---------------------------------------------")
  644. message(STATUS "OpenTelemetry: ${OPENTELEMETRY_VERSION}")
  645. message(STATUS "OpenTelemetry ABI: ${OPENTELEMETRY_ABI_VERSION_NO}")
  646. message(STATUS "ARCH: ${ARCH}")
  647. message(STATUS "CXX: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
  648. message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
  649. message(STATUS "CXXFLAGS: ${CMAKE_CXX_FLAGS}")
  650. message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}")
  651. message(STATUS "CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
  652. message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
  653. message(STATUS "---------------------------------------------")
  654. message(STATUS "opentelemetry-cpp build options")
  655. message(STATUS "---------------------------------------------")
  656. message(STATUS "WITH_API_ONLY: ${WITH_API_ONLY}")
  657. message(STATUS "WITH_NO_DEPRECATED_CODE: ${WITH_NO_DEPRECATED_CODE}")
  658. message(STATUS "WITH_ABI_VERSION_1: ${WITH_ABI_VERSION_1}")
  659. message(STATUS "WITH_ABI_VERSION_2: ${WITH_ABI_VERSION_2}")
  660. message(STATUS "OTELCPP_VERSIONED_LIBS: ${OTELCPP_VERSIONED_LIBS}")
  661. message(STATUS "OTELCPP_MAINTAINER_MODE: ${OTELCPP_MAINTAINER_MODE}")
  662. message(STATUS "WITH_STL: ${WITH_STL}")
  663. message(STATUS "WITH_GSL: ${WITH_GSL}")
  664. message(STATUS "WITH_NO_GETENV: ${WITH_NO_GETENV}")
  665. message(STATUS "---------------------------------------------")
  666. message(STATUS "opentelemetry-cpp cmake component options")
  667. message(STATUS "---------------------------------------------")
  668. message(STATUS "WITH_OTLP_GRPC: ${WITH_OTLP_GRPC}")
  669. message(STATUS "WITH_OTLP_HTTP: ${WITH_OTLP_HTTP}")
  670. message(STATUS "WITH_OTLP_FILE: ${WITH_OTLP_FILE}")
  671. message(STATUS "WITH_HTTP_CLIENT_CURL: ${WITH_HTTP_CLIENT_CURL}")
  672. message(STATUS "WITH_ZIPKIN: ${WITH_ZIPKIN}")
  673. message(STATUS "WITH_PROMETHEUS: ${WITH_PROMETHEUS}")
  674. message(STATUS "WITH_ELASTICSEARCH: ${WITH_ELASTICSEARCH}")
  675. message(STATUS "WITH_OPENTRACING: ${WITH_OPENTRACING}")
  676. message(STATUS "WITH_ETW: ${WITH_ETW}")
  677. message(STATUS "OPENTELEMETRY_BUILD_DLL: ${OPENTELEMETRY_BUILD_DLL}")
  678. message(STATUS "---------------------------------------------")
  679. message(STATUS "feature preview options")
  680. message(STATUS "---------------------------------------------")
  681. message(STATUS "WITH_ASYNC_EXPORT_PREVIEW: ${WITH_ASYNC_EXPORT_PREVIEW}")
  682. message(
  683. STATUS
  684. "WITH_THREAD_INSTRUMENTATION_PREVIEW: ${WITH_THREAD_INSTRUMENTATION_PREVIEW}"
  685. )
  686. message(
  687. STATUS "WITH_METRICS_EXEMPLAR_PREVIEW: ${WITH_METRICS_EXEMPLAR_PREVIEW}")
  688. message(STATUS "WITH_REMOVE_METER_PREVIEW: ${WITH_REMOVE_METER_PREVIEW}")
  689. message(
  690. STATUS "WITH_OTLP_GRPC_SSL_MTLS_PREVIEW: ${WITH_OTLP_GRPC_SSL_MTLS_PREVIEW}")
  691. message(STATUS "WITH_OTLP_RETRY_PREVIEW: ${WITH_OTLP_RETRY_PREVIEW}")
  692. message(STATUS "---------------------------------------------")
  693. message(STATUS "third-party options")
  694. message(STATUS "---------------------------------------------")
  695. message(STATUS "WITH_NLOHMANN_JSON: ${USE_NLOHMANN_JSON}")
  696. message(STATUS "WITH_CURL_LOGGING: ${WITH_CURL_LOGGING}")
  697. message(STATUS "WITH_OTLP_HTTP_COMPRESSION: ${WITH_OTLP_HTTP_COMPRESSION}")
  698. message(STATUS "---------------------------------------------")
  699. message(STATUS "examples and test options")
  700. message(STATUS "---------------------------------------------")
  701. message(STATUS "WITH_BENCHMARK: ${WITH_BENCHMARK}")
  702. message(STATUS "WITH_EXAMPLES: ${WITH_EXAMPLES}")
  703. message(STATUS "WITH_EXAMPLES_HTTP: ${WITH_EXAMPLES_HTTP}")
  704. message(STATUS "WITH_FUNC_TESTS: ${WITH_FUNC_TESTS}")
  705. message(STATUS "BUILD_W3CTRACECONTEXT_TEST: ${BUILD_W3CTRACECONTEXT_TEST}")
  706. message(STATUS "BUILD_TESTING: ${BUILD_TESTING}")
  707. message(STATUS "---------------------------------------------")
  708. message(STATUS "versions")
  709. message(STATUS "---------------------------------------------")
  710. message(STATUS "CMake: ${CMAKE_VERSION}")
  711. message(STATUS "GTest: ${GTest_VERSION}")
  712. message(STATUS "benchmark: ${benchmark_VERSION}")
  713. if(WITH_GSL)
  714. message(STATUS "GSL: ${GSL_VERSION}")
  715. endif()
  716. if(absl_FOUND)
  717. message(STATUS "Abseil: ${absl_VERSION}")
  718. endif()
  719. if(Protobuf_FOUND)
  720. message(STATUS "Protobuf: ${Protobuf_VERSION}")
  721. endif()
  722. if(gRPC_FOUND)
  723. message(STATUS "gRPC: ${gRPC_VERSION}")
  724. endif()
  725. if(CURL_FOUND)
  726. message(STATUS "CURL: ${CURL_VERSION}")
  727. endif()
  728. if(ZLIB_FOUND)
  729. message(STATUS "ZLIB: ${ZLIB_VERSION}")
  730. endif()
  731. if(USE_NLOHMANN_JSON)
  732. message(STATUS "nlohmann-json: ${nlohmann_json_VERSION}")
  733. endif()
  734. if(prometheus-cpp_FOUND)
  735. message(STATUS "prometheus-cpp: ${prometheus-cpp_VERSION}")
  736. endif()
  737. message(STATUS "---------------------------------------------")
  738. include("${PROJECT_SOURCE_DIR}/cmake/otel-install-functions.cmake")
  739. include(CMakePackageConfigHelpers)
  740. if(DEFINED OPENTELEMETRY_BUILD_DLL)
  741. if(NOT WIN32)
  742. message(FATAL_ERROR "Build DLL is only supported on Windows!")
  743. endif()
  744. if(NOT MSVC)
  745. message(WARNING "Build DLL is supposed to work with MSVC!")
  746. endif()
  747. if(WITH_STL)
  748. message(
  749. WARNING "Build DLL with C++ STL could cause binary incompatibility!")
  750. endif()
  751. add_definitions(-DOPENTELEMETRY_BUILD_EXPORT_DLL)
  752. endif()
  753. add_subdirectory(api)
  754. if(WITH_OPENTRACING)
  755. find_package(OpenTracing CONFIG QUIET)
  756. if(NOT OpenTracing_FOUND)
  757. set(OPENTRACING_DIR "third_party/opentracing-cpp")
  758. message(STATUS "Trying to use local ${OPENTRACING_DIR} from submodule")
  759. if(EXISTS "${PROJECT_SOURCE_DIR}/${OPENTRACING_DIR}/.git")
  760. set(SAVED_BUILD_TESTING ${BUILD_TESTING})
  761. set(BUILD_TESTING OFF)
  762. set(SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE
  763. ${CMAKE_CXX_INCLUDE_WHAT_YOU_USE})
  764. set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "")
  765. add_subdirectory(${OPENTRACING_DIR})
  766. set(BUILD_TESTING ${SAVED_BUILD_TESTING})
  767. set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE
  768. ${SAVED_CMAKE_CXX_INCLUDE_WHAT_YOU_USE})
  769. else()
  770. message(
  771. FATAL_ERROR
  772. "\nopentracing-cpp package was not found. Please either provide it manually or clone with submodules. "
  773. "To initialize, fetch and checkout any nested submodules, you can use the following command:\n"
  774. "git submodule update --init --recursive")
  775. endif()
  776. else()
  777. message(STATUS "Using external opentracing-cpp")
  778. endif()
  779. add_subdirectory(opentracing-shim)
  780. endif()
  781. if(NOT WITH_API_ONLY)
  782. set(BUILD_TESTING ${BUILD_TESTING})
  783. add_subdirectory(sdk)
  784. add_subdirectory(ext)
  785. add_subdirectory(exporters)
  786. if(BUILD_TESTING)
  787. add_subdirectory(test_common)
  788. endif()
  789. if(WITH_EXAMPLES)
  790. add_subdirectory(examples)
  791. endif()
  792. if(WITH_FUNC_TESTS)
  793. add_subdirectory(functional)
  794. endif()
  795. endif()
  796. include(cmake/opentelemetry-build-external-component.cmake)
  797. include(cmake/patch-imported-config.cmake)
  798. if(OPENTELEMETRY_INSTALL)
  799. # Install the cmake config and version files
  800. otel_install_cmake_config()
  801. # Install the components and associated files
  802. otel_install_components()
  803. # Install the thirdparty dependency definition file
  804. otel_install_thirdparty_definitions()
  805. if(BUILD_PACKAGE)
  806. include(cmake/package.cmake)
  807. include(CPack)
  808. endif()
  809. endif()