Skip to content

Commit 9de68d8

Browse files
authored
[BUILD] Support build proto as shared lib on Windows (#3714)
1 parent 578c101 commit 9de68d8

File tree

4 files changed

+258
-46
lines changed

4 files changed

+258
-46
lines changed

ci/do_ci.ps1

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,35 @@ $VCPKG_DIR = Join-Path "$SRC_DIR" "tools/vcpkg"
3434

3535
$Env:CTEST_OUTPUT_ON_FAILURE = "1"
3636

37+
function FindAndMergeDllPath {
38+
param (
39+
[string[]]$AdditionalDirs
40+
)
41+
42+
$FINAL_PATH = $env:PATH
43+
$PATH_SET = @{}
44+
$PATH_ITEMS = $FINAL_PATH -split [IO.Path]::PathSeparator
45+
foreach ($item in $PATH_ITEMS) {
46+
$PATH_SET[$item] = $true
47+
}
48+
49+
foreach ($dir in $AdditionalDirs) {
50+
$GLOB_PATTERN = Join-Path "$dir" "*.dll"
51+
$DETECTED_DLL_FILES = Get-ChildItem -Path $GLOB_PATTERN -Recurse
52+
$DETECTED_DLL_DIRS = $(foreach ($dll_file in $DETECTED_DLL_FILES) {
53+
$dll_file.Directory.FullName
54+
}) | Sort-Object | Get-Unique
55+
foreach ($dll_dir in $DETECTED_DLL_DIRS) {
56+
if (-not $PATH_SET.ContainsKey($dll_dir)) {
57+
$FINAL_PATH = "$dll_dir" + [IO.Path]::PathSeparator + $FINAL_PATH
58+
$PATH_SET[$dll_dir] = $true
59+
}
60+
}
61+
}
62+
63+
return $FINAL_PATH
64+
}
65+
3766
switch ($action) {
3867
"bazel.build" {
3968
bazel $BAZEL_STARTUP_OPTIONS build $BAZEL_OPTIONS --action_env=VCPKG_DIR=$VCPKG_DIR --deleted_packages=opentracing-shim -- //...
@@ -67,7 +96,7 @@ switch ($action) {
6796
cmake $SRC_DIR `
6897
-DVCPKG_TARGET_TRIPLET=x64-windows `
6998
-DOPENTELEMETRY_BUILD_DLL=1 `
70-
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
99+
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
71100
$exit = $LASTEXITCODE
72101
if ($exit -ne 0) {
73102
exit $exit
@@ -77,7 +106,7 @@ switch ($action) {
77106
if ($exit -ne 0) {
78107
exit $exit
79108
}
80-
$env:PATH = "$BUILD_DIR\ext\src\dll\Debug;$env:PATH"
109+
$env:PATH = FindAndMergeDllPath "$BUILD_DIR\ext\src\dll\Debug"
81110
ctest -C Debug
82111
$exit = $LASTEXITCODE
83112
if ($exit -ne 0) {
@@ -90,7 +119,7 @@ switch ($action) {
90119
-DCMAKE_CXX_STANDARD=20 `
91120
-DVCPKG_TARGET_TRIPLET=x64-windows `
92121
-DOPENTELEMETRY_BUILD_DLL=1 `
93-
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
122+
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
94123
$exit = $LASTEXITCODE
95124
if ($exit -ne 0) {
96125
exit $exit
@@ -100,7 +129,7 @@ switch ($action) {
100129
if ($exit -ne 0) {
101130
exit $exit
102131
}
103-
$env:PATH = "$BUILD_DIR\ext\src\dll\Debug;$env:PATH"
132+
$env:PATH = FindAndMergeDllPath "$BUILD_DIR\ext\src\dll\Debug"
104133
ctest -C Debug
105134
$exit = $LASTEXITCODE
106135
if ($exit -ne 0) {
@@ -125,6 +154,10 @@ switch ($action) {
125154
if ($exit -ne 0) {
126155
exit $exit
127156
}
157+
158+
$env:PATH = FindAndMergeDllPath "."
159+
Write-Output "PATH=$env:PATH"
160+
128161
ctest -C Debug
129162
$exit = $LASTEXITCODE
130163
if ($exit -ne 0) {
@@ -151,6 +184,10 @@ switch ($action) {
151184
if ($exit -ne 0) {
152185
exit $exit
153186
}
187+
188+
$env:PATH = FindAndMergeDllPath "."
189+
Write-Output "PATH=$env:PATH"
190+
154191
ctest -C Debug
155192
$exit = $LASTEXITCODE
156193
if ($exit -ne 0) {
@@ -175,6 +212,10 @@ switch ($action) {
175212
if ($exit -ne 0) {
176213
exit $exit
177214
}
215+
216+
$env:PATH = FindAndMergeDllPath "."
217+
Write-Output "PATH=$env:PATH"
218+
178219
ctest -C Debug
179220
$exit = $LASTEXITCODE
180221
if ($exit -ne 0) {
@@ -196,6 +237,10 @@ switch ($action) {
196237
if ($exit -ne 0) {
197238
exit $exit
198239
}
240+
241+
$env:PATH = FindAndMergeDllPath "."
242+
Write-Output "PATH=$env:PATH"
243+
199244
ctest -C Debug
200245
$exit = $LASTEXITCODE
201246
if ($exit -ne 0) {
@@ -208,7 +253,7 @@ switch ($action) {
208253
"-C $SRC_DIR/test_common/cmake/all-options-abiv1-preview.cmake" `
209254
-DWITH_OPENTRACING=OFF `
210255
-DVCPKG_TARGET_TRIPLET=x64-windows `
211-
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
256+
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
212257
$exit = $LASTEXITCODE
213258
if ($exit -ne 0) {
214259
exit $exit
@@ -218,6 +263,10 @@ switch ($action) {
218263
if ($exit -ne 0) {
219264
exit $exit
220265
}
266+
267+
$env:PATH = FindAndMergeDllPath "."
268+
Write-Output "PATH=$env:PATH"
269+
221270
ctest -C Debug
222271
$exit = $LASTEXITCODE
223272
if ($exit -ne 0) {
@@ -240,7 +289,7 @@ switch ($action) {
240289
if ($exit -ne 0) {
241290
exit $exit
242291
}
243-
$env:PATH = "$BUILD_DIR\ext\src\dll\Debug;$env:PATH"
292+
$env:PATH = FindAndMergeDllPath "$BUILD_DIR\ext\src\dll\Debug"
244293
ctest -C Debug
245294
$exit = $LASTEXITCODE
246295
if ($exit -ne 0) {
@@ -264,6 +313,10 @@ switch ($action) {
264313
if ($exit -ne 0) {
265314
exit $exit
266315
}
316+
317+
$env:PATH = FindAndMergeDllPath "."
318+
Write-Output "PATH=$env:PATH"
319+
267320
ctest -C Debug
268321
$exit = $LASTEXITCODE
269322
if ($exit -ne 0) {
@@ -316,21 +369,22 @@ switch ($action) {
316369
cd "$BUILD_DIR"
317370

318371
if (Test-Path Env:\CXX_STANDARD) {
319-
$CXX_STANDARD = [int](Get-Item Env:\CXX_STANDARD).Value
320-
} else {
321-
$CXX_STANDARD = 17
372+
$CXX_STANDARD = [int](Get-Item Env:\CXX_STANDARD).Value
373+
}
374+
else {
375+
$CXX_STANDARD = 17
322376
}
323377
if (-not $CXX_STANDARD) {
324-
$CXX_STANDARD = 17
378+
$CXX_STANDARD = 17
325379
}
326380
Write-Host "Using CXX_STANDARD: $CXX_STANDARD"
327381

328382
$CMAKE_OPTIONS = @(
329-
"-DCMAKE_CXX_STANDARD=$CXX_STANDARD",
330-
"-DCMAKE_CXX_STANDARD_REQUIRED=ON",
331-
"-DCMAKE_CXX_EXTENSIONS=OFF",
332-
"-DVCPKG_TARGET_TRIPLET=x64-windows",
333-
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
383+
"-DCMAKE_CXX_STANDARD=$CXX_STANDARD",
384+
"-DCMAKE_CXX_STANDARD_REQUIRED=ON",
385+
"-DCMAKE_CXX_EXTENSIONS=OFF",
386+
"-DVCPKG_TARGET_TRIPLET=x64-windows",
387+
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake"
334388
)
335389

336390
cmake $SRC_DIR `
@@ -352,6 +406,10 @@ switch ($action) {
352406
exit $exit
353407
}
354408

409+
$env:PATH = FindAndMergeDllPath "."
410+
411+
Write-Output "PATH=$env:PATH"
412+
355413
ctest -C Debug
356414
$exit = $LASTEXITCODE
357415
if ($exit -ne 0) {
@@ -364,7 +422,9 @@ switch ($action) {
364422
exit $exit
365423
}
366424

367-
$env:PATH = "$INSTALL_TEST_DIR\bin;$env:PATH"
425+
$env:PATH = FindAndMergeDllPath "$INSTALL_TEST_DIR\bin"
426+
427+
Write-Output "PATH=$env:PATH"
368428

369429
$CMAKE_OPTIONS_STRING = $CMAKE_OPTIONS -join " "
370430

@@ -389,11 +449,14 @@ switch ($action) {
389449
mkdir "$BUILD_DIR\install_test"
390450
cd "$BUILD_DIR\install_test"
391451

452+
$env:PATH = FindAndMergeDllPath "."
453+
Write-Output "PATH=$env:PATH"
454+
392455
cmake $CMAKE_OPTIONS `
393-
"-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" `
394-
"-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" `
395-
"-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" `
396-
-S "$SRC_DIR\install\test\cmake"
456+
"-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" `
457+
"-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" `
458+
"-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" `
459+
-S "$SRC_DIR\install\test\cmake"
397460

398461
$exit = $LASTEXITCODE
399462
if ($exit -ne 0) {
@@ -414,10 +477,10 @@ switch ($action) {
414477
Remove-Item -Recurse -Force "$INSTALL_TEST_DIR\*"
415478

416479
$CMAKE_OPTIONS = @(
417-
"-DCMAKE_CXX_STANDARD=17",
418-
"-DVCPKG_TARGET_TRIPLET=x64-windows",
419-
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake",
420-
"-DOPENTELEMETRY_BUILD_DLL=1"
480+
"-DCMAKE_CXX_STANDARD=17",
481+
"-DVCPKG_TARGET_TRIPLET=x64-windows",
482+
"-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake",
483+
"-DOPENTELEMETRY_BUILD_DLL=1"
421484
)
422485

423486
cmake $SRC_DIR `
@@ -452,7 +515,12 @@ switch ($action) {
452515
exit $exit
453516
}
454517

518+
$env:PATH = FindAndMergeDllPath "."
519+
520+
Write-Output "PATH=$env:PATH"
521+
455522
ctest -C Debug
523+
456524
$exit = $LASTEXITCODE
457525
if ($exit -ne 0) {
458526
exit $exit
@@ -464,9 +532,9 @@ switch ($action) {
464532
exit $exit
465533
}
466534

467-
$env:PATH = "$INSTALL_TEST_DIR\bin;$env:PATH"
535+
$env:PATH = FindAndMergeDllPath "$INSTALL_TEST_DIR\bin"
468536

469-
echo "$env:PATH"
537+
Write-Output "PATH=$env:PATH"
470538

471539
$CMAKE_OPTIONS_STRING = $CMAKE_OPTIONS -join " "
472540

@@ -484,11 +552,15 @@ switch ($action) {
484552
mkdir "$BUILD_DIR\install_test"
485553
cd "$BUILD_DIR\install_test"
486554

555+
$env:PATH = FindAndMergeDllPath "."
556+
557+
Write-Output "PATH=$env:PATH"
558+
487559
cmake $CMAKE_OPTIONS `
488-
"-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" `
489-
"-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" `
490-
"-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" `
491-
-S "$SRC_DIR\install\test\cmake"
560+
"-DCMAKE_PREFIX_PATH=$INSTALL_TEST_DIR" `
561+
"-DINSTALL_TEST_CMAKE_OPTIONS=$CMAKE_OPTIONS_STRING" `
562+
"-DINSTALL_TEST_COMPONENTS=$EXPECTED_COMPONENTS_STRING" `
563+
-S "$SRC_DIR\install\test\cmake"
492564

493565
$exit = $LASTEXITCODE
494566
if ($exit -ne 0) {

cmake/opentelemetry-proto.cmake

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,10 @@ foreach(IMPORT_DIR ${PROTOBUF_IMPORT_DIRS})
174174
list(APPEND PROTOBUF_INCLUDE_FLAGS "-I${IMPORT_DIR}")
175175
endforeach()
176176

177-
set(PROTOBUF_COMMON_FLAGS "--proto_path=${PROTO_PATH}"
178-
"--cpp_out=${GENERATED_PROTOBUF_PATH}")
177+
set(PROTOBUF_COMMON_FLAGS
178+
"--proto_path=${PROTO_PATH}"
179+
"--cpp_out=dllexport_decl=OPENTELEMETRY_PROTO_API:${GENERATED_PROTOBUF_PATH}"
180+
)
179181
# --experimental_allow_proto3_optional is available from 3.13 and be stable and
180182
# enabled by default from 3.16
181183
if(Protobuf_VERSION AND Protobuf_VERSION VERSION_LESS "3.16")
@@ -276,13 +278,13 @@ add_custom_command(
276278
DEPENDS ${PROTOBUF_GENERATE_DEPENDS})
277279

278280
unset(OTELCPP_PROTO_TARGET_OPTIONS)
279-
if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore")
280-
list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC)
281-
elseif((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY")
282-
AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS))
281+
if((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY")
282+
AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS))
283283
list(APPEND OTELCPP_PROTO_TARGET_OPTIONS SHARED)
284+
set(OTELCPP_PROTO_LIB_TYPE "SHARED_LIBRARY")
284285
else()
285286
list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC)
287+
set(OTELCPP_PROTO_LIB_TYPE "STATIC_LIBRARY")
286288
endif()
287289

288290
set(OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto)
@@ -299,13 +301,26 @@ add_library(
299301
${METRICS_SERVICE_PB_CPP_FILE})
300302
set_target_version(opentelemetry_proto)
301303

304+
if(OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY")
305+
project_build_tools_set_shared_library_declaration(OPENTELEMETRY_PROTO_API
306+
opentelemetry_proto)
307+
else()
308+
project_build_tools_set_static_library_declaration(OPENTELEMETRY_PROTO_API
309+
opentelemetry_proto)
310+
endif()
311+
302312
target_include_directories(
303313
opentelemetry_proto PUBLIC "$<BUILD_INTERFACE:${GENERATED_PROTOBUF_PATH}>"
304314
"$<INSTALL_INTERFACE:include>")
305315

306316
# Disable include-what-you-use and clang-tidy on generated code.
307-
set_target_properties(opentelemetry_proto PROPERTIES CXX_INCLUDE_WHAT_YOU_USE ""
308-
CXX_CLANG_TIDY "")
317+
set_target_properties(
318+
opentelemetry_proto
319+
PROPERTIES CXX_INCLUDE_WHAT_YOU_USE ""
320+
CXX_CLANG_TIDY ""
321+
C_VISIBILITY_PRESET "hidden"
322+
CXX_VISIBILITY_PRESET "hidden"
323+
VISIBILITY_INLINES_HIDDEN OFF)
309324
if(NOT Protobuf_INCLUDE_DIRS AND TARGET protobuf::libprotobuf)
310325
get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf
311326
INTERFACE_INCLUDE_DIRECTORIES)
@@ -323,10 +338,33 @@ if(WITH_OTLP_GRPC)
323338
${LOGS_SERVICE_GRPC_PB_CPP_FILE} ${METRICS_SERVICE_GRPC_PB_CPP_FILE})
324339
set_target_version(opentelemetry_proto_grpc)
325340

341+
if(OTELCPP_PROTO_LIB_TYPE STREQUAL "SHARED_LIBRARY")
342+
if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore")
343+
# The codes generated by gRPC plugin do not support dll export/import
344+
# declarations. To work around this, we enable WINDOWS_EXPORT_ALL_SYMBOLS
345+
# property to export all symbols when building a shared library.
346+
# TODO: This can be removed once gRPC plugin supports dll export/import.
347+
set_target_properties(opentelemetry_proto_grpc
348+
PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
349+
endif()
350+
endif()
351+
326352
# Disable include-what-you-use and clang-tidy on generated code.
353+
# The codes generated by gRPC plugin do not support symbol visibility
354+
# declarations for public APIs. To work around this, we set visibility
355+
# to default and disable hidden inline visibility. Otherwise, building
356+
# a shared library will fail when user changes the default visibility
357+
# to hidden (e.g., via -fvisibility=hidden compiler flag).
358+
# TODO: C_VISIBILITY_PRESET, CXX_VISIBILITY_PRESET, and
359+
# VISIBILITY_INLINES_HIDDEN can be removed once gRPC plugin supports symbol
360+
# visibility declarations.
327361
set_target_properties(
328-
opentelemetry_proto_grpc PROPERTIES CXX_INCLUDE_WHAT_YOU_USE ""
329-
CXX_CLANG_TIDY "")
362+
opentelemetry_proto_grpc
363+
PROPERTIES CXX_INCLUDE_WHAT_YOU_USE ""
364+
CXX_CLANG_TIDY ""
365+
C_VISIBILITY_PRESET "default"
366+
CXX_VISIBILITY_PRESET "default"
367+
VISIBILITY_INLINES_HIDDEN OFF)
330368

331369
list(APPEND OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto_grpc)
332370
target_link_libraries(opentelemetry_proto_grpc PUBLIC opentelemetry_proto)
@@ -338,7 +376,8 @@ if(WITH_OTLP_GRPC)
338376
# opentelemetry_exporter_otlp_grpc_client as a static library.
339377
get_target_property(grpc_lib_type gRPC::grpc++ TYPE)
340378

341-
if(grpc_lib_type STREQUAL "SHARED_LIBRARY")
379+
if(grpc_lib_type STREQUAL "SHARED_LIBRARY" OR OTELCPP_PROTO_LIB_TYPE STREQUAL
380+
"SHARED_LIBRARY")
342381
target_link_libraries(opentelemetry_proto_grpc PUBLIC gRPC::grpc++)
343382
endif()
344383
set_target_properties(opentelemetry_proto_grpc PROPERTIES EXPORT_NAME

0 commit comments

Comments
 (0)