Skip to content

Commit 9597fca

Browse files
committed
Fixes grpc linking for OTLP exporter's tests
Force build opentelemetry_proto and OTLP exporters as static libraries when protobuf or grpc are built static.
1 parent 4b6f52a commit 9597fca

File tree

3 files changed

+199
-27
lines changed

3 files changed

+199
-27
lines changed

cmake/opentelemetry-proto.cmake

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,39 @@ elseif(PROTOBUF_VERSION AND PROTOBUF_VERSION VERSION_LESS "3.16")
221221
list(APPEND PROTOBUF_COMMON_FLAGS "--experimental_allow_proto3_optional")
222222
endif()
223223

224+
# protobuf uses numerous global variables, which can lead to conflicts when a
225+
# user's dynamic libraries, executables, and otel-cpp are all built with
226+
# -fvisibility=hidden and linked against a statically built protobuf library.
227+
# This may result in crashes. To prevent such conflicts, we also need to build
228+
# opentelemetry_exporter_otlp_grpc_client as a static library.
229+
if(TARGET protobuf::libprotobuf)
230+
get_target_property(protobuf_lib_type protobuf::libprotobuf TYPE)
231+
# protobuf_lib_type may be "INTERFACE_LIBRARY" in some build systems, such as
232+
# conan.
233+
if(protobuf_lib_type STREQUAL "INTERFACE_LIBRARY")
234+
project_build_tools_recursive_scan_imported_locations(
235+
protobuf_lib_files TARGET_NAME protobuf::libprotobuf TARGET_MATCH
236+
".*(protobuf).*")
237+
foreach(protobuf_lib_file ${protobuf_lib_files})
238+
if(protobuf_lib_file MATCHES
239+
"(^|[\\\\\\/])[^\\\\\\/]*protobuf[^\\\\\\/]*.a$")
240+
set(protobuf_lib_type "STATIC_LIBRARY")
241+
break()
242+
endif()
243+
endforeach()
244+
endif()
245+
else()
246+
set(protobuf_lib_type "SHARED_LIBRARY")
247+
target_link_libraries(opentelemetry_proto PUBLIC ${Protobuf_LIBRARIES})
248+
foreach(protobuf_lib_file ${Protobuf_LIBRARIES})
249+
if(protobuf_lib_file MATCHES
250+
"(^|[\\\\\\/])[^\\\\\\/]*protobuf[^\\\\\\/]*.a$")
251+
set(protobuf_lib_type "STATIC_LIBRARY")
252+
break()
253+
endif()
254+
endforeach()
255+
endif()
256+
224257
set(PROTOBUF_GENERATED_FILES
225258
${COMMON_PB_H_FILE}
226259
${COMMON_PB_CPP_FILE}
@@ -293,7 +326,8 @@ add_custom_command(
293326
unset(OTELCPP_PROTO_TARGET_OPTIONS)
294327
if(CMAKE_SYSTEM_NAME MATCHES "Windows|MinGW|WindowsStore")
295328
list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC)
296-
elseif(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)
329+
elseif((NOT protobuf_lib_type STREQUAL "STATIC_LIBRARY")
330+
AND (NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS))
297331
list(APPEND OTELCPP_PROTO_TARGET_OPTIONS SHARED)
298332
else()
299333
list(APPEND OTELCPP_PROTO_TARGET_OPTIONS STATIC)
@@ -302,6 +336,7 @@ endif()
302336
set(OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto)
303337
add_library(
304338
opentelemetry_proto
339+
${OPENTELEMETRY_OTLP_PROTO_LIB_TYPE}
305340
${OTELCPP_PROTO_TARGET_OPTIONS}
306341
${COMMON_PB_CPP_FILE}
307342
${RESOURCE_PB_CPP_FILE}
@@ -314,9 +349,8 @@ add_library(
314349
set_target_version(opentelemetry_proto)
315350

316351
target_include_directories(
317-
opentelemetry_proto
318-
PUBLIC "$<BUILD_INTERFACE:${GENERATED_PROTOBUF_PATH}>"
319-
"$<INSTALL_INTERFACE:include>")
352+
opentelemetry_proto PUBLIC "$<BUILD_INTERFACE:${GENERATED_PROTOBUF_PATH}>"
353+
"$<INSTALL_INTERFACE:include>")
320354

321355
# Disable include-what-you-use on generated code.
322356
set_target_properties(opentelemetry_proto PROPERTIES CXX_INCLUDE_WHAT_YOU_USE
@@ -334,8 +368,9 @@ endif()
334368
if(WITH_OTLP_GRPC)
335369
add_library(
336370
opentelemetry_proto_grpc
337-
${OTELCPP_PROTO_TARGET_OPTIONS} ${TRACE_SERVICE_GRPC_PB_CPP_FILE}
338-
${LOGS_SERVICE_GRPC_PB_CPP_FILE} ${METRICS_SERVICE_GRPC_PB_CPP_FILE})
371+
${OPENTELEMETRY_OTLP_PROTO_LIB_TYPE} ${OTELCPP_PROTO_TARGET_OPTIONS}
372+
${TRACE_SERVICE_GRPC_PB_CPP_FILE} ${LOGS_SERVICE_GRPC_PB_CPP_FILE}
373+
${METRICS_SERVICE_GRPC_PB_CPP_FILE})
339374
set_target_version(opentelemetry_proto_grpc)
340375

341376
# Disable include-what-you-use on generated code.
@@ -382,7 +417,8 @@ else() # cmake 3.8 or lower
382417
target_link_libraries(opentelemetry_proto PUBLIC ${Protobuf_LIBRARIES})
383418
endif()
384419

385-
# this is needed on some older grcp versions specifically conan recipe for grpc/1.54.3
420+
# this is needed on some older grcp versions specifically conan recipe for
421+
# grpc/1.54.3
386422
if(WITH_OTLP_GRPC)
387423
if(TARGET absl::synchronization)
388424
target_link_libraries(opentelemetry_proto_grpc

cmake/tools.cmake

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ function(project_build_tools_get_imported_location OUTPUT_VAR_NAME TARGET_NAME)
9999
get_target_property(TARGET_TYPE ${TARGET_NAME} TYPE)
100100
if(TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
101101
# For interface libraries, do not attempt to retrieve imported location.
102-
set(${OUTPUT_VAR_NAME} "" PARENT_SCOPE)
102+
set(${OUTPUT_VAR_NAME}
103+
""
104+
PARENT_SCOPE)
103105
return()
104106
endif()
105107

@@ -220,3 +222,97 @@ function(project_build_tools_patch_default_imported_config)
220222
endif()
221223
endforeach()
222224
endfunction()
225+
226+
function(__project_build_tools_recursive_scan_unwrap OUTPUT_VAR INPUT_VAR)
227+
# With sub-expressions
228+
if(INPUT_VAR MATCHES "^\\\$<.*>:([^>]+)>?$")
229+
set(${OUTPUT_VAR}
230+
"${CMAKE_MATCH_1}"
231+
PARENT_SCOPE)
232+
elseif(INPUT_VAR MATCHES "^\\\$<[^:]+:([^>]+)>?$")
233+
set(${OUTPUT_VAR}
234+
"${CMAKE_MATCH_1}"
235+
PARENT_SCOPE)
236+
else()
237+
set(${OUTPUT_VAR}
238+
"${INPUT_VAR}"
239+
PARENT_SCOPE)
240+
endif()
241+
endfunction()
242+
243+
macro(__project_build_tools_recursive_scan_imported_locations)
244+
if(NOT DEFINED __project_build_tools_recursive_call_level)
245+
set(__project_build_tools_recursive_call_level 1)
246+
else()
247+
math(EXPR __project_build_tools_recursive_call_level
248+
"${__project_build_tools_recursive_call_level} + 1")
249+
endif()
250+
foreach(TARGET_NAME_ORIGIN_${__project_build_tools_recursive_call_level}
251+
${ARGN})
252+
if(TARGET_NAME_ORIGIN_${__project_build_tools_recursive_call_level} MATCHES
253+
"^\\\$<.*>?$")
254+
__project_build_tools_recursive_scan_unwrap(
255+
TARGET_NAME
256+
"${TARGET_NAME_ORIGIN_${__project_build_tools_recursive_call_level}}")
257+
else()
258+
set(TARGET_NAME
259+
"${TARGET_NAME_ORIGIN_${__project_build_tools_recursive_call_level}}")
260+
endif()
261+
if(NOT DEFINED
262+
__project_build_tools_recursive_scan_imported_locations_${TARGET_NAME})
263+
set(__project_build_tools_recursive_scan_imported_locations_${TARGET_NAME}
264+
TRUE)
265+
set(__lib_path)
266+
project_build_tools_get_imported_location(__lib_path ${TARGET_NAME})
267+
if(__lib_path)
268+
list(APPEND __OUTPUT_VAR ${__lib_path})
269+
endif()
270+
271+
set(__TARGET_LINK_LIBRARIES)
272+
get_target_property(__TARGET_LINK_LIBRARIES ${TARGET_NAME}
273+
INTERFACE_LINK_LIBRARIES)
274+
if(__SCAN_OPTION_TARGET_MATCH)
275+
set(__TARGET_LINK_LIBRARIES_SELECTED)
276+
foreach(__TARGET_LINK_LIBRARIES_ITEM IN LISTS __TARGET_LINK_LIBRARIES)
277+
set(__TARGET_MATCHED FALSE)
278+
foreach(__MATCH_RULE ${__SCAN_OPTION_TARGET_MATCH})
279+
if(__TARGET_LINK_LIBRARIES_ITEM MATCHES "${__MATCH_RULE}")
280+
set(__TARGET_MATCHED TRUE)
281+
break()
282+
endif()
283+
endforeach()
284+
if(__TARGET_MATCHED)
285+
list(APPEND __TARGET_LINK_LIBRARIES_SELECTED
286+
${__TARGET_LINK_LIBRARIES_ITEM})
287+
endif()
288+
endforeach(__TARGET_LINK_LIBRARIES_ITEM IN LISTS
289+
__TARGET_LINK_LIBRARIES)
290+
else()
291+
set(__TARGET_LINK_LIBRARIES_SELECTED ${__TARGET_LINK_LIBRARIES})
292+
endif()
293+
294+
if(__TARGET_LINK_LIBRARIES_SELECTED)
295+
__project_build_tools_recursive_scan_imported_locations(
296+
${__TARGET_LINK_LIBRARIES_SELECTED})
297+
endif()
298+
endif()
299+
endforeach()
300+
math(EXPR __project_build_tools_recursive_call_level
301+
"${__project_build_tools_recursive_call_level} - 1")
302+
endmacro()
303+
304+
function(project_build_tools_recursive_scan_imported_locations OUTPUT_VAR)
305+
set(optionArgs)
306+
set(oneValueArgs)
307+
set(multiValueArgs TARGET_NAME TARGET_MATCH)
308+
cmake_parse_arguments(__SCAN_OPTION "${optionArgs}" "${oneValueArgs}"
309+
"${multiValueArgs}" "${ARGN}")
310+
set(__OUTPUT_VAR)
311+
312+
__project_build_tools_recursive_scan_imported_locations(
313+
${__SCAN_OPTION_TARGET_NAME})
314+
315+
set(${OUTPUT_VAR}
316+
${__OUTPUT_VAR}
317+
PARENT_SCOPE)
318+
endfunction()

exporters/otlp/CMakeLists.txt

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
# Copyright The OpenTelemetry Authors
22
# SPDX-License-Identifier: Apache-2.0
33

4+
if(protobuf_lib_type STREQUAL "STATIC_LIBRARY")
5+
set(OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE STATIC)
6+
else()
7+
set(OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE)
8+
endif()
9+
410
add_library(
511
opentelemetry_otlp_recordable
6-
src/otlp_environment.cc src/otlp_log_recordable.cc src/otlp_recordable.cc
7-
src/otlp_populate_attribute_utils.cc src/otlp_recordable_utils.cc
12+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE}
13+
src/otlp_environment.cc
14+
src/otlp_log_recordable.cc
15+
src/otlp_recordable.cc
16+
src/otlp_populate_attribute_utils.cc
17+
src/otlp_recordable_utils.cc
818
src/otlp_metric_utils.cc)
919
set_target_properties(opentelemetry_otlp_recordable PROPERTIES EXPORT_NAME
1020
otlp_recordable)
@@ -23,10 +33,34 @@ target_link_libraries(opentelemetry_otlp_recordable
2333

2434
if(WITH_OTLP_GRPC)
2535
find_package(gRPC REQUIRED)
36+
# gRPC uses numerous global variables, which can lead to conflicts when a
37+
# user's dynamic libraries, executables, and otel-cpp are all built with
38+
# -fvisibility=hidden and linked against a statically built gRPC library. This
39+
# may result in crashes. To prevent such conflicts, we also need to build
40+
# opentelemetry_exporter_otlp_grpc_client as a static library.
41+
get_target_property(grpc_lib_type gRPC::grpc++ TYPE)
42+
# grpc_lib_type may be "INTERFACE_LIBRARY" in some build systems, such as
43+
# conan.
44+
if(grpc_lib_type STREQUAL "INTERFACE_LIBRARY")
45+
project_build_tools_recursive_scan_imported_locations(
46+
grpc_lib_files TARGET_NAME gRPC::grpc++ TARGET_MATCH ".*(grpc|gRPC).*")
47+
foreach(grpc_lib_file ${grpc_lib_files})
48+
if(grpc_lib_file MATCHES "(^|[\\\\\\/])[^\\\\\\/]*grpc[^\\\\\\/]*.a$")
49+
set(grpc_lib_type "STATIC_LIBRARY")
50+
break()
51+
endif()
52+
endforeach()
53+
endif()
54+
if(grpc_lib_type STREQUAL "STATIC_LIBRARY" OR protobuf_lib_type STREQUAL
55+
"STATIC_LIBRARY")
56+
set(OPENTELEMETRY_OTLP_GRPC_CLIENT_LIB_TYPE STATIC)
57+
else()
58+
set(OPENTELEMETRY_OTLP_GRPC_CLIENT_LIB_TYPE)
59+
endif()
2660
add_library(
2761
opentelemetry_exporter_otlp_grpc_client
28-
src/otlp_grpc_client.cc src/otlp_grpc_client_factory.cc
29-
src/otlp_grpc_utils.cc)
62+
${OPENTELEMETRY_OTLP_GRPC_CLIENT_LIB_TYPE} src/otlp_grpc_client.cc
63+
src/otlp_grpc_client_factory.cc src/otlp_grpc_utils.cc)
3064
set_target_properties(opentelemetry_exporter_otlp_grpc_client
3165
PROPERTIES EXPORT_NAME otlp_grpc_client)
3266
set_target_version(opentelemetry_exporter_otlp_grpc_client)
@@ -60,8 +94,8 @@ if(WITH_OTLP_GRPC)
6094

6195
add_library(
6296
opentelemetry_exporter_otlp_grpc
63-
src/otlp_grpc_exporter.cc src/otlp_grpc_exporter_factory.cc
64-
src/otlp_grpc_exporter_options.cc)
97+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_grpc_exporter.cc
98+
src/otlp_grpc_exporter_factory.cc src/otlp_grpc_exporter_options.cc)
6599

66100
set_target_properties(opentelemetry_exporter_otlp_grpc
67101
PROPERTIES EXPORT_NAME otlp_grpc_exporter)
@@ -76,7 +110,7 @@ if(WITH_OTLP_GRPC)
76110

77111
add_library(
78112
opentelemetry_exporter_otlp_grpc_log
79-
src/otlp_grpc_log_record_exporter.cc
113+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_grpc_log_record_exporter.cc
80114
src/otlp_grpc_log_record_exporter_factory.cc
81115
src/otlp_grpc_log_record_exporter_options.cc)
82116

@@ -94,7 +128,8 @@ if(WITH_OTLP_GRPC)
94128

95129
add_library(
96130
opentelemetry_exporter_otlp_grpc_metrics
97-
src/otlp_grpc_metric_exporter.cc src/otlp_grpc_metric_exporter_factory.cc
131+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_grpc_metric_exporter.cc
132+
src/otlp_grpc_metric_exporter_factory.cc
98133
src/otlp_grpc_metric_exporter_options.cc)
99134

100135
set_target_properties(opentelemetry_exporter_otlp_grpc_metrics
@@ -111,8 +146,10 @@ if(WITH_OTLP_GRPC)
111146
endif()
112147

113148
if(WITH_OTLP_HTTP)
114-
add_library(opentelemetry_exporter_otlp_http_client src/otlp_http.cc
115-
src/otlp_http_client.cc)
149+
add_library(
150+
opentelemetry_exporter_otlp_http_client
151+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http.cc
152+
src/otlp_http_client.cc)
116153
set_target_properties(opentelemetry_exporter_otlp_http_client
117154
PROPERTIES EXPORT_NAME otlp_http_client)
118155
set_target_version(opentelemetry_exporter_otlp_http_client)
@@ -141,8 +178,8 @@ if(WITH_OTLP_HTTP)
141178

142179
add_library(
143180
opentelemetry_exporter_otlp_http
144-
src/otlp_http_exporter.cc src/otlp_http_exporter_factory.cc
145-
src/otlp_http_exporter_options.cc)
181+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http_exporter.cc
182+
src/otlp_http_exporter_factory.cc src/otlp_http_exporter_options.cc)
146183

147184
set_target_properties(opentelemetry_exporter_otlp_http
148185
PROPERTIES EXPORT_NAME otlp_http_exporter)
@@ -157,7 +194,7 @@ if(WITH_OTLP_HTTP)
157194

158195
add_library(
159196
opentelemetry_exporter_otlp_http_log
160-
src/otlp_http_log_record_exporter.cc
197+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http_log_record_exporter.cc
161198
src/otlp_http_log_record_exporter_factory.cc
162199
src/otlp_http_log_record_exporter_options.cc)
163200

@@ -175,7 +212,8 @@ if(WITH_OTLP_HTTP)
175212

176213
add_library(
177214
opentelemetry_exporter_otlp_http_metric
178-
src/otlp_http_metric_exporter.cc src/otlp_http_metric_exporter_factory.cc
215+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_http_metric_exporter.cc
216+
src/otlp_http_metric_exporter_factory.cc
179217
src/otlp_http_metric_exporter_options.cc)
180218

181219
set_target_properties(opentelemetry_exporter_otlp_http_metric
@@ -192,7 +230,8 @@ if(WITH_OTLP_HTTP)
192230
endif()
193231

194232
if(WITH_OTLP_FILE)
195-
add_library(opentelemetry_exporter_otlp_file_client src/otlp_file_client.cc)
233+
add_library(opentelemetry_exporter_otlp_file_client
234+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_client.cc)
196235
set_target_properties(opentelemetry_exporter_otlp_file_client
197236
PROPERTIES EXPORT_NAME otlp_file_client)
198237
set_target_version(opentelemetry_exporter_otlp_file_client)
@@ -216,8 +255,8 @@ if(WITH_OTLP_FILE)
216255

217256
add_library(
218257
opentelemetry_exporter_otlp_file
219-
src/otlp_file_exporter.cc src/otlp_file_exporter_factory.cc
220-
src/otlp_file_exporter_options.cc)
258+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_exporter.cc
259+
src/otlp_file_exporter_factory.cc src/otlp_file_exporter_options.cc)
221260

222261
set_target_properties(opentelemetry_exporter_otlp_file
223262
PROPERTIES EXPORT_NAME otlp_file_exporter)
@@ -232,7 +271,7 @@ if(WITH_OTLP_FILE)
232271

233272
add_library(
234273
opentelemetry_exporter_otlp_file_log
235-
src/otlp_file_log_record_exporter.cc
274+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_log_record_exporter.cc
236275
src/otlp_file_log_record_exporter_factory.cc
237276
src/otlp_file_log_record_exporter_options.cc)
238277

@@ -250,7 +289,8 @@ if(WITH_OTLP_FILE)
250289

251290
add_library(
252291
opentelemetry_exporter_otlp_file_metric
253-
src/otlp_file_metric_exporter.cc src/otlp_file_metric_exporter_factory.cc
292+
${OPENTELEMETRY_OTLP_TARGETS_LIB_TYPE} src/otlp_file_metric_exporter.cc
293+
src/otlp_file_metric_exporter_factory.cc
254294
src/otlp_file_metric_exporter_options.cc)
255295

256296
set_target_properties(opentelemetry_exporter_otlp_file_metric

0 commit comments

Comments
 (0)