diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ee56c0f25..4c08d1cd91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,7 @@ jobs: - name: install dependencies run: | sudo -E apt-get update - sudo -E apt-get install -y zlib1g-dev libcurl4-openssl-dev libabsl-dev libprotobuf-dev libgrpc++-dev protobuf-compiler protobuf-compiler-grpc + sudo -E apt-get install -y zlib1g-dev libabsl-dev libprotobuf-dev libgrpc++-dev protobuf-compiler protobuf-compiler-grpc - name: run fetch content cmake test run: | ./ci/do_ci.sh cmake.fetch_content.test diff --git a/CMakeLists.txt b/CMakeLists.txt index bfe0071498..6083010b3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -304,6 +304,42 @@ endif() # GNUInstallDirs. include(GNUInstallDirs) +# +# Do we need HTTP CLIENT CURL ? +# + +if(WITH_OTLP_HTTP + OR WITH_ELASTICSEARCH + OR WITH_ZIPKIN + OR BUILD_W3CTRACECONTEXT_TEST + OR WITH_EXAMPLES_HTTP) + set(WITH_HTTP_CLIENT_CURL ON) +else() + set(WITH_HTTP_CLIENT_CURL OFF) +endif() + +# +# Do we need ZLIB ? +# + +if((NOT WITH_API_ONLY) + AND WITH_HTTP_CLIENT_CURL + AND WITH_OTLP_HTTP_COMPRESSION) + include("${opentelemetry-cpp_SOURCE_DIR}/cmake/zlib.cmake") +endif() + +# +# Do we need CURL ? +# + +if((NOT WITH_API_ONLY) AND WITH_HTTP_CLIENT_CURL) + include("${opentelemetry-cpp_SOURCE_DIR}/cmake/curl.cmake") +endif() + +# +# Do we need prometheus-cpp ? +# + if(WITH_PROMETHEUS) include("${opentelemetry-cpp_SOURCE_DIR}/cmake/prometheus-cpp.cmake") endif() @@ -387,50 +423,6 @@ if(WITH_OTLP_GRPC set(CMAKE_CXX_CLANG_TIDY ${SAVED_CMAKE_CXX_CLANG_TIDY}) endif() -# -# Do we need HTTP CLIENT CURL ? -# - -if(WITH_OTLP_HTTP - OR WITH_ELASTICSEARCH - OR WITH_ZIPKIN - OR BUILD_W3CTRACECONTEXT_TEST - OR WITH_EXAMPLES_HTTP) - set(WITH_HTTP_CLIENT_CURL ON) -else() - set(WITH_HTTP_CLIENT_CURL OFF) -endif() - -# -# Do we need CURL ? -# - -if((NOT WITH_API_ONLY) AND WITH_HTTP_CLIENT_CURL) - # No specific version required. - find_package(CURL REQUIRED) - # Set the CURL_VERSION from the legacy CURL_VERSION_STRING Required for CMake - # versions below 4.0 - if(NOT DEFINED CURL_VERSION AND DEFINED CURL_VERSION_STRING) - set(CURL_VERSION ${CURL_VERSION_STRING}) - endif() -endif() - -# -# Do we need ZLIB ? -# - -if((NOT WITH_API_ONLY) - AND WITH_HTTP_CLIENT_CURL - AND WITH_OTLP_HTTP_COMPRESSION) - # No specific version required. - find_package(ZLIB REQUIRED) - # Set the ZLIB_VERSION from the legacy ZLIB_VERSION_STRING Required for CMake - # versions below 3.26 - if(NOT DEFINED ZLIB_VERSION AND DEFINED ZLIB_VERSION_STRING) - set(ZLIB_VERSION ${ZLIB_VERSION_STRING}) - endif() -endif() - # # Do we need NLOHMANN_JSON ? # @@ -658,11 +650,11 @@ endif() if(gRPC_FOUND) message(STATUS "gRPC: ${gRPC_VERSION}") endif() -if(CURL_FOUND) - message(STATUS "CURL: ${CURL_VERSION}") +if(CURL_VERSION) + message(STATUS "CURL: ${CURL_VERSION} (${CURL_PROVIDER})") endif() -if(ZLIB_FOUND) - message(STATUS "ZLIB: ${ZLIB_VERSION}") +if(ZLIB_VERSION) + message(STATUS "ZLIB: ${ZLIB_VERSION} (${ZLIB_PROVIDER})") endif() if(USE_NLOHMANN_JSON) message( diff --git a/cmake/curl.cmake b/cmake/curl.cmake new file mode 100644 index 0000000000..994c1fbd2a --- /dev/null +++ b/cmake/curl.cmake @@ -0,0 +1,76 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# Import the curl target (CURL::libcurl). +# 1. Find an installed curl package +# 2. Use FetchContent to fetch and build curl from GitHub + +# Find the curl package with the default search mode +find_package(CURL QUIET) +set(CURL_PROVIDER "find_package") + +if(NOT CURL_FOUND) + FetchContent_Declare( + "curl" + GIT_REPOSITORY "https://github.com/curl/curl.git" + GIT_TAG "${curl_GIT_TAG}" + ) + set(CURL_PROVIDER "fetch_repository") + + if(OPENTELEMETRY_INSTALL) + set(_CURL_DISABLE_INSTALL OFF) + else() + set(_CURL_DISABLE_INSTALL ON) + endif() + + if(DEFINED BUILD_SHARED_LIBS) + set(_SAVED_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) + endif() + + set(CURL_DISABLE_INSTALL ${_CURL_DISABLE_INSTALL} CACHE BOOL "" FORCE) + set(CURL_USE_LIBPSL OFF CACHE BOOL "" FORCE) + set(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE) + set(BUILD_LIBCURL_DOCS OFF CACHE BOOL "" FORCE) + set(BUILD_MISC_DOCS OFF CACHE BOOL "" FORCE) + set(ENABLE_CURL_MANUAL OFF CACHE BOOL "" FORCE) + set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) + + FetchContent_MakeAvailable(curl) + + # Restore BUILD_SHARED_LIBS + if(DEFINED _SAVED_BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ${_SAVED_BUILD_SHARED_LIBS} CACHE BOOL "" FORCE) + else() + unset(BUILD_SHARED_LIBS CACHE) + endif() + + # Set the CURL_VERSION variable from the git tag. + string(REGEX REPLACE "^curl-([0-9]+)_([0-9]+)_([0-9]+)$" "\\1.\\2.\\3" CURL_VERSION "${curl_GIT_TAG}") + + # disable iwyu and clang-tidy + foreach(_curl_target libcurl_shared libcurl_static) + if(TARGET ${_curl_target}) + set_target_properties(${_curl_target} PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" + CXX_CLANG_TIDY "") + endif() + endforeach() +endif() + +# Set the CURL_VERSION from the legacy CURL_VERSION_STRING Required for CMake +# versions below 4.0 +if(NOT CURL_VERSION AND CURL_VERSION_STRING) + set(CURL_VERSION ${CURL_VERSION_STRING}) +endif() + +# Add the main CURL::libcurl alias target if missing. Prefer the shared target followed by the static target +if(NOT TARGET CURL::libcurl) + if(TARGET libcurl_shared) + add_library(CURL::libcurl ALIAS libcurl_shared) + elseif(TARGET libcurl_static) + add_library(CURL::libcurl ALIAS libcurl_static) + endif() +endif() + +if(NOT TARGET CURL::libcurl) + message(FATAL_ERROR "The required curl target (CURL::libcurl) was not imported.") +endif() diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake new file mode 100644 index 0000000000..ad616e0d28 --- /dev/null +++ b/cmake/zlib.cmake @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# ZLIB must be found as an installed package for now. +# Fetching ZLIB and building in-tree is not supported. +# Protobuf, gRPC, prometheus-cpp, civetweb, CURL, and other dependencies require ZLIB and import its target. +# When ZLIB::ZLIB is an alias of the shared library then inconsistent linking may occur. + +find_package(ZLIB REQUIRED) +set(ZLIB_PROVIDER "find_package") + +# Set the ZLIB_VERSION from the legacy ZLIB_VERSION_STRING Required for CMake +# versions below 3.26 +if(NOT ZLIB_VERSION AND ZLIB_VERSION_STRING) + set(ZLIB_VERSION ${ZLIB_VERSION_STRING}) +endif() + +if(NOT TARGET ZLIB::ZLIB) + message(FATAL_ERROR "The required zlib target (ZLIB::ZLIB) was not imported.") +endif() diff --git a/examples/http/CMakeLists.txt b/examples/http/CMakeLists.txt index 693781f598..0aff680302 100644 --- a/examples/http/CMakeLists.txt +++ b/examples/http/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(http_server server.cc) target_link_libraries( http_client PRIVATE opentelemetry-cpp::trace opentelemetry-cpp::http_client_curl - opentelemetry-cpp::ostream_span_exporter ${CURL_LIBRARIES}) + opentelemetry-cpp::ostream_span_exporter CURL::libcurl) target_link_libraries( http_server diff --git a/exporters/zipkin/CMakeLists.txt b/exporters/zipkin/CMakeLists.txt index 548a9fd44d..9fc92ba7a5 100644 --- a/exporters/zipkin/CMakeLists.txt +++ b/exporters/zipkin/CMakeLists.txt @@ -59,7 +59,7 @@ if(BUILD_TESTING) ${GMOCK_LIB} opentelemetry_exporter_zipkin_trace opentelemetry_resources - ${CURL_LIBRARIES}) + CURL::libcurl) gtest_add_tests( TARGET zipkin_exporter_test diff --git a/ext/src/http/client/curl/CMakeLists.txt b/ext/src/http/client/curl/CMakeLists.txt index 0c1d8c6195..d238a1c4dd 100644 --- a/ext/src/http/client/curl/CMakeLists.txt +++ b/ext/src/http/client/curl/CMakeLists.txt @@ -11,40 +11,10 @@ set_target_version(opentelemetry_http_client_curl) target_link_libraries(opentelemetry_http_client_curl PUBLIC opentelemetry_common) -unset(CURL_IMPORTED_TARGET_NAME) - -foreach(FIND_CURL_IMPORTED_TARGET CURL::libcurl CURL::libcurl_shared - CURL::libcurl_static) - if(TARGET ${FIND_CURL_IMPORTED_TARGET}) - set(CURL_IMPORTED_TARGET_NAME ${FIND_CURL_IMPORTED_TARGET}) - break() - endif() -endforeach() - -if(TARGET ${CURL_IMPORTED_TARGET_NAME}) - target_link_libraries( - opentelemetry_http_client_curl - PUBLIC opentelemetry_ext - PRIVATE ${CURL_IMPORTED_TARGET_NAME}) - - # Some versions of libcurl do not export the link directories, which may cause - # link errors - project_build_tools_get_imported_location(CURL_LIB_FILE_PATH - ${CURL_IMPORTED_TARGET_NAME}) - get_filename_component(CURL_LIB_DIR_PATH "${CURL_LIB_FILE_PATH}" DIRECTORY) - - if(CURL_LIB_DIR_PATH) - target_link_directories(opentelemetry_http_client_curl PUBLIC - "$") - endif() -else() - target_include_directories(opentelemetry_http_client_curl - INTERFACE "${CURL_INCLUDE_DIRS}") - target_link_libraries( - opentelemetry_http_client_curl - PUBLIC opentelemetry_ext - PRIVATE ${CURL_LIBRARIES}) -endif() +target_link_libraries( + opentelemetry_http_client_curl + PUBLIC opentelemetry_ext + PRIVATE CURL::libcurl) if(WITH_CURL_LOGGING) target_compile_definitions(opentelemetry_http_client_curl @@ -52,19 +22,10 @@ if(WITH_CURL_LOGGING) endif() if(WITH_OTLP_HTTP_COMPRESSION) - if(TARGET ZLIB::ZLIB) - target_link_libraries( - opentelemetry_http_client_curl - PUBLIC opentelemetry_ext - PRIVATE ZLIB::ZLIB) - else() - target_include_directories(opentelemetry_http_client_curl - INTERFACE "${ZLIB_INCLUDE_DIRS}") - target_link_libraries( - opentelemetry_http_client_curl - PUBLIC opentelemetry_ext - PRIVATE ${ZLIB_LIBRARIES}) - endif() + target_link_libraries( + opentelemetry_http_client_curl + PUBLIC opentelemetry_ext + PRIVATE ZLIB::ZLIB) endif() otel_add_component(COMPONENT ext_http_curl TARGETS diff --git a/ext/test/http/CMakeLists.txt b/ext/test/http/CMakeLists.txt index f4d3774735..b7707bd8c2 100644 --- a/ext/test/http/CMakeLists.txt +++ b/ext/test/http/CMakeLists.txt @@ -4,28 +4,10 @@ if(WITH_HTTP_CLIENT_CURL) set(FILENAME curl_http_test) add_executable(${FILENAME} ${FILENAME}.cc) - target_link_libraries(${FILENAME} ${GMOCK_LIB} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT}) - - unset(CURL_IMPORTED_TARGET_NAME) - - foreach(FIND_CURL_IMPORTED_TARGET CURL::libcurl CURL::libcurl_shared - CURL::libcurl_static) - if(TARGET ${FIND_CURL_IMPORTED_TARGET}) - set(CURL_IMPORTED_TARGET_NAME ${FIND_CURL_IMPORTED_TARGET}) - break() - endif() - endforeach() - - if(TARGET ${CURL_IMPORTED_TARGET_NAME}) - target_link_libraries(${FILENAME} opentelemetry_http_client_curl - opentelemetry_common ${CURL_IMPORTED_TARGET_NAME}) - else() - target_include_directories(${FILENAME} PRIVATE ${CURL_INCLUDE_DIRS}) - target_link_libraries(${FILENAME} ${CURL_LIBRARIES} - opentelemetry_http_client_curl opentelemetry_common) - endif() - + target_link_libraries( + ${FILENAME} + PRIVATE ${GMOCK_LIB} ${GTEST_BOTH_LIBRARIES} opentelemetry_http_client_curl + opentelemetry_common CURL::libcurl) gtest_add_tests( TARGET ${FILENAME} TEST_PREFIX ext.http.curl. diff --git a/ext/test/w3c_tracecontext_http_test_server/CMakeLists.txt b/ext/test/w3c_tracecontext_http_test_server/CMakeLists.txt index 53e7a27ccf..095da7ad80 100644 --- a/ext/test/w3c_tracecontext_http_test_server/CMakeLists.txt +++ b/ext/test/w3c_tracecontext_http_test_server/CMakeLists.txt @@ -6,4 +6,4 @@ target_link_libraries( w3c_tracecontext_http_test_server PRIVATE ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace opentelemetry_http_client_curl opentelemetry_exporter_ostream_span - ${CURL_LIBRARIES} nlohmann_json::nlohmann_json) + CURL::libcurl nlohmann_json::nlohmann_json)