diff --git a/ci/do_ci.ps1 b/ci/do_ci.ps1 index 82c70ce8ef..573d6bac72 100644 --- a/ci/do_ci.ps1 +++ b/ci/do_ci.ps1 @@ -34,6 +34,35 @@ $VCPKG_DIR = Join-Path "$SRC_DIR" "tools/vcpkg" $Env:CTEST_OUTPUT_ON_FAILURE = "1" +function FindAndMergeDllPath { + param ( + [string[]]$AdditionalDirs + ) + + $FINAL_PATH = $env:PATH + $PATH_SET = @{} + $PATH_ITEMS = $FINAL_PATH -split [IO.Path]::PathSeparator + foreach ($item in $PATH_ITEMS) { + $PATH_SET[$item] = $true + } + + foreach ($dir in $AdditionalDirs) { + $GLOB_PATTERN = Join-Path "$dir" "*.dll" + $DETECTED_DLL_FILES = Get-ChildItem -Path $GLOB_PATTERN -Recurse + $DETECTED_DLL_DIRS = $(foreach ($dll_file in $DETECTED_DLL_FILES) { + $dll_file.Directory.FullName + }) | Sort-Object | Get-Unique + foreach ($dll_dir in $DETECTED_DLL_DIRS) { + if (-not $PATH_SET.ContainsKey($dll_dir)) { + $FINAL_PATH = "$dll_dir" + [IO.Path]::PathSeparator + $FINAL_PATH + $PATH_SET[$dll_dir] = $true + } + } + } + + return $FINAL_PATH +} + switch ($action) { "bazel.build" { bazel $BAZEL_STARTUP_OPTIONS build $BAZEL_OPTIONS --action_env=VCPKG_DIR=$VCPKG_DIR --deleted_packages=opentracing-shim -- //... @@ -67,7 +96,7 @@ switch ($action) { cmake $SRC_DIR ` -DVCPKG_TARGET_TRIPLET=x64-windows ` -DOPENTELEMETRY_BUILD_DLL=1 ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -77,7 +106,7 @@ switch ($action) { if ($exit -ne 0) { exit $exit } - $env:PATH = "$BUILD_DIR\ext\src\dll\Debug;$env:PATH" + $env:PATH = FindAndMergeDllPath "$BUILD_DIR\ext\src\dll\Debug" ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -90,7 +119,7 @@ switch ($action) { -DCMAKE_CXX_STANDARD=20 ` -DVCPKG_TARGET_TRIPLET=x64-windows ` -DOPENTELEMETRY_BUILD_DLL=1 ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -100,7 +129,7 @@ switch ($action) { if ($exit -ne 0) { exit $exit } - $env:PATH = "$BUILD_DIR\ext\src\dll\Debug;$env:PATH" + $env:PATH = FindAndMergeDllPath "$BUILD_DIR\ext\src\dll\Debug" ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -125,6 +154,10 @@ switch ($action) { if ($exit -ne 0) { exit $exit } + + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -151,6 +184,10 @@ switch ($action) { if ($exit -ne 0) { exit $exit } + + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -175,6 +212,10 @@ switch ($action) { if ($exit -ne 0) { exit $exit } + + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -196,6 +237,10 @@ switch ($action) { if ($exit -ne 0) { exit $exit } + + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -208,7 +253,7 @@ switch ($action) { "-C $SRC_DIR/test_common/cmake/all-options-abiv1-preview.cmake" ` -DWITH_OPENTRACING=OFF ` -DVCPKG_TARGET_TRIPLET=x64-windows ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -218,6 +263,10 @@ switch ($action) { if ($exit -ne 0) { exit $exit } + + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -240,7 +289,7 @@ switch ($action) { if ($exit -ne 0) { exit $exit } - $env:PATH = "$BUILD_DIR\ext\src\dll\Debug;$env:PATH" + $env:PATH = FindAndMergeDllPath "$BUILD_DIR\ext\src\dll\Debug" ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -264,6 +313,10 @@ switch ($action) { if ($exit -ne 0) { exit $exit } + + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -316,21 +369,22 @@ switch ($action) { cd "$BUILD_DIR" if (Test-Path Env:\CXX_STANDARD) { - $CXX_STANDARD = [int](Get-Item Env:\CXX_STANDARD).Value - } else { - $CXX_STANDARD = 17 + $CXX_STANDARD = [int](Get-Item Env:\CXX_STANDARD).Value + } + else { + $CXX_STANDARD = 17 } if (-not $CXX_STANDARD) { - $CXX_STANDARD = 17 + $CXX_STANDARD = 17 } Write-Host "Using CXX_STANDARD: $CXX_STANDARD" $CMAKE_OPTIONS = @( - "-DCMAKE_CXX_STANDARD=$CXX_STANDARD", - "-DCMAKE_CXX_STANDARD_REQUIRED=ON", - "-DCMAKE_CXX_EXTENSIONS=OFF", - "-DVCPKG_TARGET_TRIPLET=x64-windows", - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + "-DCMAKE_CXX_STANDARD=$CXX_STANDARD", + "-DCMAKE_CXX_STANDARD_REQUIRED=ON", + "-DCMAKE_CXX_EXTENSIONS=OFF", + "-DVCPKG_TARGET_TRIPLET=x64-windows", + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" ) cmake $SRC_DIR ` @@ -352,6 +406,10 @@ switch ($action) { exit $exit } + $env:PATH = FindAndMergeDllPath "." + + Write-Output "PATH=$env:PATH" + ctest -C Debug $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -364,7 +422,9 @@ switch ($action) { exit $exit } - $env:PATH = "$INSTALL_TEST_DIR\bin;$env:PATH" + $env:PATH = FindAndMergeDllPath "$INSTALL_TEST_DIR\bin" + + Write-Output "PATH=$env:PATH" $CMAKE_OPTIONS_STRING = $CMAKE_OPTIONS -join " " @@ -389,11 +449,14 @@ switch ($action) { mkdir "$BUILD_DIR\install_test" cd "$BUILD_DIR\install_test" + $env:PATH = FindAndMergeDllPath "." + Write-Output "PATH=$env:PATH" + cmake $CMAKE_OPTIONS ` - "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" ` - "-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" ` - "-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" ` - -S "$SRC_DIR\install\test\cmake" + "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" ` + "-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" ` + "-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" ` + -S "$SRC_DIR\install\test\cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { @@ -414,10 +477,10 @@ switch ($action) { Remove-Item -Recurse -Force "$INSTALL_TEST_DIR\*" $CMAKE_OPTIONS = @( - "-DCMAKE_CXX_STANDARD=17", - "-DVCPKG_TARGET_TRIPLET=x64-windows", - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake", - "-DOPENTELEMETRY_BUILD_DLL=1" + "-DCMAKE_CXX_STANDARD=17", + "-DVCPKG_TARGET_TRIPLET=x64-windows", + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake", + "-DOPENTELEMETRY_BUILD_DLL=1" ) cmake $SRC_DIR ` @@ -452,7 +515,12 @@ switch ($action) { exit $exit } + $env:PATH = FindAndMergeDllPath "." + + Write-Output "PATH=$env:PATH" + ctest -C Debug + $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -464,9 +532,9 @@ switch ($action) { exit $exit } - $env:PATH = "$INSTALL_TEST_DIR\bin;$env:PATH" + $env:PATH = FindAndMergeDllPath "$INSTALL_TEST_DIR\bin" - echo "$env:PATH" + Write-Output "PATH=$env:PATH" $CMAKE_OPTIONS_STRING = $CMAKE_OPTIONS -join " " @@ -484,11 +552,15 @@ switch ($action) { mkdir "$BUILD_DIR\install_test" cd "$BUILD_DIR\install_test" + $env:PATH = FindAndMergeDllPath "." + + Write-Output "PATH=$env:PATH" + cmake $CMAKE_OPTIONS ` - "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" ` - "-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" ` - "-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" ` - -S "$SRC_DIR\install\test\cmake" + "-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" ` + "-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" ` + "-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" ` + -S "$SRC_DIR\install\test\cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { diff --git a/cmake/opentelemetry-proto.cmake b/cmake/opentelemetry-proto.cmake index 648d21d2f2..c77a87488d 100644 --- a/cmake/opentelemetry-proto.cmake +++ b/cmake/opentelemetry-proto.cmake @@ -174,8 +174,10 @@ foreach(IMPORT_DIR ${PROTOBUF_IMPORT_DIRS}) list(APPEND PROTOBUF_INCLUDE_FLAGS "-I${IMPORT_DIR}") endforeach() -set(PROTOBUF_COMMON_FLAGS "--proto_path=${PROTO_PATH}" - "--cpp_out=${GENERATED_PROTOBUF_PATH}") +set(PROTOBUF_COMMON_FLAGS + "--proto_path=${PROTO_PATH}" + "--cpp_out=dllexport_decl=OPENTELEMETRY_PROTO_API:${GENERATED_PROTOBUF_PATH}" +) # --experimental_allow_proto3_optional is available from 3.13 and be stable and # enabled by default from 3.16 if(Protobuf_VERSION AND Protobuf_VERSION VERSION_LESS "3.16") @@ -276,13 +278,13 @@ add_custom_command( DEPENDS ${PROTOBUF_GENERATE_DEPENDS}) unset(OTELCPP_PROTO_TARGET_OPTIONS) -if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore") - list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC) -elseif((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY") - AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)) +if((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY") + AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)) list(APPEND OTELCPP_PROTO_TARGET_OPTIONS SHARED) + set(OTELCPP_PROTO_LIB_TYPE "SHARED_LIBRARY") else() list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC) + set(OTELCPP_PROTO_LIB_TYPE "STATIC_LIBRARY") endif() set(OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto) @@ -299,13 +301,26 @@ add_library( ${METRICS_SERVICE_PB_CPP_FILE}) set_target_version(opentelemetry_proto) +if(OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY") + project_build_tools_set_shared_library_declaration(OPENTELEMETRY_PROTO_API + opentelemetry_proto) +else() + project_build_tools_set_static_library_declaration(OPENTELEMETRY_PROTO_API + opentelemetry_proto) +endif() + target_include_directories( opentelemetry_proto PUBLIC "$" "$") # Disable include-what-you-use and clang-tidy on generated code. -set_target_properties(opentelemetry_proto PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" - CXX_CLANG_TIDY "") +set_target_properties( + opentelemetry_proto + PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" + CXX_CLANG_TIDY "" + C_VISIBILITY_PRESET "hidden" + CXX_VISIBILITY_PRESET "hidden" + VISIBILITY_INLINES_HIDDEN OFF) if(NOT Protobuf_INCLUDE_DIRS AND TARGET protobuf::libprotobuf) get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) @@ -323,10 +338,33 @@ if(WITH_OTLP_GRPC) ${LOGS_SERVICE_GRPC_PB_CPP_FILE} ${METRICS_SERVICE_GRPC_PB_CPP_FILE}) set_target_version(opentelemetry_proto_grpc) + if(OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY") + if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore") + # The codes generated by gRPC plugin do not support dll export/import + # declarations. To work around this, we enable WINDOWS_EXPORT_ALL_SYMBOLS + # property to export all symbols when building a shared library. + # TODO: This can be removed once gRPC plugin supports dll export/import. + set_target_properties(opentelemetry_proto_grpc + PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + endif() + endif() + # Disable include-what-you-use and clang-tidy on generated code. + # The codes generated by gRPC plugin do not support symbol visibility + # declarations for public APIs. To work around this, we set visibility + # to default and disable hidden inline visibility. Otherwise, building + # a shared library will fail when user changes the default visibility + # to hidden (e.g., via -fvisibility=hidden compiler flag). + # TODO: C_VISIBILITY_PRESET, CXX_VISIBILITY_PRESET, and + # VISIBILITY_INLINES_HIDDEN can be removed once gRPC plugin supports symbol + # visibility declarations. set_target_properties( - opentelemetry_proto_grpc PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" - CXX_CLANG_TIDY "") + opentelemetry_proto_grpc + PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "" + CXX_CLANG_TIDY "" + C_VISIBILITY_PRESET "default" + CXX_VISIBILITY_PRESET "default" + VISIBILITY_INLINES_HIDDEN OFF) list(APPEND OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto_grpc) target_link_libraries(opentelemetry_proto_grpc PUBLIC opentelemetry_proto) @@ -338,7 +376,8 @@ if(WITH_OTLP_GRPC) # opentelemetry_exporter_otlp_grpc_client as a static library. get_target_property(grpc_lib_type gRPC::grpc++ TYPE) - if(grpc_lib_type STREQUAL "SHARED_LIBRARY") + if(grpc_lib_type STREQUAL "SHARED_LIBRARY" OR OTELCPP_PROTO_LIB_TYPE STREQUAL + "SHARED_LIBRARY") target_link_libraries(opentelemetry_proto_grpc PUBLIC gRPC::grpc++) endif() set_target_properties(opentelemetry_proto_grpc PROPERTIES EXPORT_NAME diff --git a/cmake/tools.cmake b/cmake/tools.cmake index 43ac5156d4..9988f73300 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -222,3 +222,100 @@ function(project_build_tools_patch_default_imported_config) endif() endforeach() endfunction() + +function(project_build_tools_set_export_declaration OUTPUT_VARNAME) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang|Intel|XL|XLClang") + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${OUTPUT_VARNAME} + "__attribute__((__dllexport__))" + PARENT_SCOPE) + else() + set(${OUTPUT_VARNAME} + "__attribute__((visibility(\"default\")))" + PARENT_SCOPE) + endif() + elseif(MSVC) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${OUTPUT_VARNAME} + "__declspec(dllexport)" + PARENT_SCOPE) + else() + set(${OUTPUT_VARNAME} + "" + PARENT_SCOPE) + endif() + elseif(SunPro) + set(${OUTPUT_VARNAME} + "__global" + PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${OUTPUT_VARNAME} + "__declspec(dllexport)" + PARENT_SCOPE) + else() + set(${OUTPUT_VARNAME} + "" + PARENT_SCOPE) + endif() +endfunction() + +function(project_build_tools_set_import_declaration OUTPUT_VARNAME) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang|Intel|XL|XLClang") + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${OUTPUT_VARNAME} + "__attribute__((__dllimport__))" + PARENT_SCOPE) + else() + set(${OUTPUT_VARNAME} + "" + PARENT_SCOPE) + endif() + elseif(MSVC) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${OUTPUT_VARNAME} + "__declspec(dllimport)" + PARENT_SCOPE) + else() + set(${OUTPUT_VARNAME} + "" + PARENT_SCOPE) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + set(${OUTPUT_VARNAME} + "__global" + PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(${OUTPUT_VARNAME} + "__declspec(dllimport)" + PARENT_SCOPE) + else() + set(${OUTPUT_VARNAME} + "" + PARENT_SCOPE) + endif() +endfunction() + +function(project_build_tools_set_shared_library_declaration DEFINITION_VARNAME) + project_build_tools_set_export_declaration(EXPORT_DECLARATION) + project_build_tools_set_import_declaration(IMPORT_DECLARATION) + foreach(TARGET_NAME ${ARGN}) + target_compile_definitions( + ${TARGET_NAME} INTERFACE "${DEFINITION_VARNAME}=${IMPORT_DECLARATION}") + target_compile_definitions( + ${TARGET_NAME} PRIVATE "${DEFINITION_VARNAME}=${EXPORT_DECLARATION}") + endforeach() +endfunction() + +function(project_build_tools_set_static_library_declaration DEFINITION_VARNAME) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang|Intel|XL|XLClang") + foreach(TARGET_NAME ${ARGN}) + target_compile_definitions( + ${TARGET_NAME} + PUBLIC "${DEFINITION_VARNAME}=__attribute__((visibility(\"default\")))") + endforeach() + else() + foreach(TARGET_NAME ${ARGN}) + target_compile_definitions(${TARGET_NAME} PUBLIC "${DEFINITION_VARNAME}=") + endforeach() + endif() +endfunction() diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 23a5cd6b6c..bb7634a07c 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -250,10 +250,12 @@ if(WITH_OTLP_HTTP) target_link_libraries( opentelemetry_exporter_otlp_http_client - PUBLIC opentelemetry_sdk opentelemetry_ext - # Links flags of opentelemetry_http_client_curl should be public when - # building internal components - PRIVATE opentelemetry_proto + PUBLIC opentelemetry_sdk + opentelemetry_ext + # Links flags of opentelemetry_http_client_curl should be public when + # building internal components + "$" + PRIVATE "$" "$" "$" "$") @@ -409,7 +411,9 @@ if(WITH_OTLP_FILE) target_link_libraries( opentelemetry_exporter_otlp_file_client PUBLIC opentelemetry_sdk opentelemetry_common - PRIVATE opentelemetry_proto $) + "$" + PRIVATE "$" + "$") target_include_directories( opentelemetry_exporter_otlp_file_client