Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 102 additions & 30 deletions ci/do_ci.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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 -- //...
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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 `
Expand All @@ -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) {
Expand All @@ -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 " "

Expand All @@ -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) {
Expand All @@ -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 `
Expand Down Expand Up @@ -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
Expand All @@ -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 " "

Expand All @@ -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) {
Expand Down
61 changes: 50 additions & 11 deletions cmake/opentelemetry-proto.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand All @@ -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 "$<BUILD_INTERFACE:${GENERATED_PROTOBUF_PATH}>"
"$<INSTALL_INTERFACE:include>")

# 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)
Expand All @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gRPC does not seem well supported when built as a windows dll. See https://chromium.googlesource.com/external/github.com/grpc/grpc/+/HEAD/BUILDING.md#windows_a-note-on-building-shared-libs-dlls

Should this be something the project tries to support and if so can it be a separate PR? It is unclear if we can/should support gRPC as a windows dll and test it in CI.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve reviewed the gRPC-generated code and confirmed it doesn’t contain global variables, so forcing it to build as static libraries should be safe. However, this might confuse users, create many duplicate symbols, and increase linker workload, similar to #3620.

We should discuss whether to build the gRPC code as a DLL or keep it as static libraries. I can rarely attend the SIG meeting due to the time zone, so could we discuss this on GitHub or Slack, or could someone share the outcome of the discussion with me afterward?

# 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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concerned about this - this will increase the DLL size, export internal implementation details, and also potential symbol conflict - better to document these limitations as TODO to revisit in future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments have been added. We can either use the static otel-cpp libraries directly or enable ext/src/dll, which bundles all .lib files into a single DLL.

With static otel-cpp libraries, each linked DLL/EXE gets its own copy of the symbols. Using ext/src/dll ensures there is only one copy of these symbols after linking, so this approach is no worse than before.

Once gRPC supports export declarations, we can further optimize this.

See also: googleapis/google-cloud-cpp#5849 and grpc/grpc#33032

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting visibility to "default" might export more symbols than intended. Is this intended? If yes, please document as comment why do we need it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is default value on Unix like system. And this is for users who change the default settings by -fvisibility=hidden, so it do not increase symbols than before.
Just like WINDOWS_EXPORT_ALL_SYMBOLS on Windows, we need something like dllexport_decl=XXX in protobuf, but gRPC do not support it now. we can optimize it when gRPC support this feature.

@see googleapis/google-cloud-cpp#5849 and grpc/grpc#33032

VISIBILITY_INLINES_HIDDEN OFF)

list(APPEND OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto_grpc)
target_link_libraries(opentelemetry_proto_grpc PUBLIC opentelemetry_proto)
Expand All @@ -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
Expand Down
Loading
Loading