opentelemetry-cpp icon indicating copy to clipboard operation
opentelemetry-cpp copied to clipboard

cmake build fails on macOS

Open itsjamie opened this issue 1 year ago • 4 comments

Running with the follow cmake definitions.

OTEL Version: v1.16.1 Abseil Version: 20240722.0 Protobuf Version: v26.1 gRPC Version: v1.63.2

-DCMAKE_PREFIX_PATH="/$prefix/../grpc;/$prefix/../abseil-cpp;/$prefix/../protobuf" -DCMAKE_CXX_STANDARD=17 -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DWITH_OTLP_GRPC=ON -DWITH_ABSEIL=ON -DWITH_STL=ON -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX="/${prefix}" -DOPENTELEMETRY_INSTALL=ON

With the grpc, abseil, and protobuf prefix path definitions all being compiled from source versions with PIC enabled, results in the following error:

FAILED: libopentelemetry_proto_grpc.dylib 
: && /usr/bin/clang++ -O3 -DNDEBUG -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -dynamiclib -Wl,-headerpad_max_install_names  -o libopentelemetry_proto_grpc.dylib -install_name @rpath/libopentelemetry_proto_grpc.dylib CMakeFiles/opentelemetry_proto_grpc.dir/generated/third_party/opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service.grpc.pb.cc.o CMakeFiles/opentelemetry_proto_grpc.dir/generated/third_party/opentelemetry-proto/opentelemetry/proto/collector/logs/v1/logs_service.grpc.pb.cc.o CMakeFiles/opentelemetry_proto_grpc.dir/generated/third_party/opentelemetry-proto/opentelemetry/proto/collector/metrics/v1/metrics_service.grpc.pb.cc.o  -Wl,-rpath,/Users/jstackhouse/myproj/build/opentelemetry-cpp/build -Wl,-rpath,/opt/grpc/lib  libopentelemetry_proto.dylib  /opt/abseil-cpp/lib/libabsl_synchronization.a  /opt/protobuf/lib/libprotobuf.a  /opt/grpc/lib/libz.dylib  /opt/abseil-cpp/lib/libabsl_log_internal_check_op.a  /opt/abseil-cpp/lib/libabsl_leak_check.a  /opt/abseil-cpp/lib/libabsl_die_if_null.a  /opt/abseil-cpp/lib/libabsl_log_internal_conditions.a  /opt/abseil-cpp/lib/libabsl_log_internal_message.a  /opt/abseil-cpp/lib/libabsl_log_internal_nullguard.a  /opt/abseil-cpp/lib/libabsl_examine_stack.a  /opt/abseil-cpp/lib/libabsl_log_internal_format.a  /opt/abseil-cpp/lib/libabsl_log_internal_proto.a  /opt/abseil-cpp/lib/libabsl_log_internal_log_sink_set.a  /opt/abseil-cpp/lib/libabsl_log_sink.a  /opt/abseil-cpp/lib/libabsl_log_entry.a  /opt/abseil-cpp/lib/libabsl_flags_internal.a  /opt/abseil-cpp/lib/libabsl_flags_marshalling.a  /opt/abseil-cpp/lib/libabsl_flags_reflection.a  /opt/abseil-cpp/lib/libabsl_flags_config.a  /opt/abseil-cpp/lib/libabsl_flags_program_name.a  /opt/abseil-cpp/lib/libabsl_flags_private_handle_accessor.a  /opt/abseil-cpp/lib/libabsl_flags_commandlineflag.a  /opt/abseil-cpp/lib/libabsl_flags_commandlineflag_internal.a  /opt/abseil-cpp/lib/libabsl_log_initialize.a  /opt/abseil-cpp/lib/libabsl_log_globals.a  /opt/abseil-cpp/lib/libabsl_vlog_config_internal.a  /opt/abseil-cpp/lib/libabsl_log_internal_fnmatch.a  /opt/abseil-cpp/lib/libabsl_log_internal_globals.a  /opt/abseil-cpp/lib/libabsl_raw_hash_set.a  /opt/abseil-cpp/lib/libabsl_hash.a  /opt/abseil-cpp/lib/libabsl_city.a  /opt/abseil-cpp/lib/libabsl_low_level_hash.a  /opt/abseil-cpp/lib/libabsl_hashtablez_sampler.a  /opt/abseil-cpp/lib/libabsl_statusor.a  /opt/abseil-cpp/lib/libabsl_status.a  /opt/abseil-cpp/lib/libabsl_cord.a  /opt/abseil-cpp/lib/libabsl_cordz_info.a  /opt/abseil-cpp/lib/libabsl_cord_internal.a  /opt/abseil-cpp/lib/libabsl_cordz_functions.a  /opt/abseil-cpp/lib/libabsl_exponential_biased.a  /opt/abseil-cpp/lib/libabsl_cordz_handle.a  /opt/abseil-cpp/lib/libabsl_synchronization.a  /opt/abseil-cpp/lib/libabsl_graphcycles_internal.a  /opt/abseil-cpp/lib/libabsl_kernel_timeout_internal.a  /opt/abseil-cpp/lib/libabsl_stacktrace.a  /opt/abseil-cpp/lib/libabsl_symbolize.a  /opt/abseil-cpp/lib/libabsl_malloc_internal.a  /opt/abseil-cpp/lib/libabsl_debugging_internal.a  /opt/abseil-cpp/lib/libabsl_demangle_internal.a  /opt/abseil-cpp/lib/libabsl_demangle_rust.a  /opt/abseil-cpp/lib/libabsl_decode_rust_punycode.a  /opt/abseil-cpp/lib/libabsl_utf8_for_code_point.a  /opt/abseil-cpp/lib/libabsl_time.a  /opt/abseil-cpp/lib/libabsl_civil_time.a  /opt/abseil-cpp/lib/libabsl_time_zone.a  -Wl,-framework,CoreFoundation  /opt/abseil-cpp/lib/libabsl_crc_cord_state.a  /opt/abseil-cpp/lib/libabsl_crc32c.a  /opt/abseil-cpp/lib/libabsl_crc_internal.a  /opt/abseil-cpp/lib/libabsl_crc_cpu_detect.a  /opt/abseil-cpp/lib/libabsl_bad_optional_access.a  /opt/abseil-cpp/lib/libabsl_strerror.a  /opt/abseil-cpp/lib/libabsl_str_format_internal.a  /opt/abseil-cpp/lib/libabsl_bad_variant_access.a  /opt/protobuf/lib/libutf8_validity.a  /opt/abseil-cpp/lib/libabsl_strings.a  /opt/abseil-cpp/lib/libabsl_int128.a  /opt/abseil-cpp/lib/libabsl_strings_internal.a  /opt/abseil-cpp/lib/libabsl_string_view.a  /opt/abseil-cpp/lib/libabsl_base.a  /opt/abseil-cpp/lib/libabsl_spinlock_wait.a  /opt/abseil-cpp/lib/libabsl_throw_delegate.a  /opt/abseil-cpp/lib/libabsl_raw_logging_internal.a  /opt/abseil-cpp/lib/libabsl_log_severity.a && :
ld: warning: ignoring duplicate libraries: '/opt/abseil-cpp/lib/libabsl_synchronization.a'
Undefined symbols for architecture arm64:
  "grpc::Status::OK", referenced from:
      grpc::Status grpc::GenericDeserialize<grpc::ProtoBufferReader, google::protobuf::MessageLite>(grpc::ByteBuffer*, google::protobuf::MessageLite*) in trace_service.grpc.pb.cc.o
      grpc::Status grpc::GenericSerialize<grpc::ProtoBufferWriter, google::protobuf::MessageLite>(google::protobuf::MessageLite const&, grpc::ByteBuffer*, bool*) in trace_service.grpc.pb.cc.o
      grpc::Status grpc::GenericSerialize<grpc::ProtoBufferWriter, google::protobuf::MessageLite>(google::protobuf::MessageLite const&, grpc::ByteBuffer*, bool*) in trace_service.grpc.pb.cc.o
... (more grpc undefined symbols)

Looking into this, because the gRPC is compiled as a static library, there is no PUBLIC link to the libopentelemetry_proto_grpc target. Which at build time seems to lead to this having missing symbols.

I believe looking at how homebrew compiles this, it's possible that the issue relates to that they add:

ENV.append "LDFLAGS", "-Wl,-undefined,dynamic_lookup" if OS.mac?

Which would allow this link step to proceed and resolve later when I assume the static gRPC would be compiled into some future library that would then provide these symbols.

itsjamie avatar Aug 16 '24 16:08 itsjamie

To build otel-cpp as a shared library, gRPC must also be built as shared libraries to avoid symbol conflicts in multiple runtime targets, which could lead to crashes.

owent avatar Aug 27 '24 08:08 owent

@owent, if this is the only supported method then I propose the CMake build should be changed to fail here:

https://github.com/open-telemetry/opentelemetry-cpp/blob/main/cmake/opentelemetry-proto.cmake#L350-L353

If BUILD_SHARED_LIBS is ON and the gRPC build is found to be STATIC.

itsjamie avatar Aug 31 '24 15:08 itsjamie

@owent, if this is the only supported method then I propose the CMake build should be changed to fail here:

https://github.com/open-telemetry/opentelemetry-cpp/blob/main/cmake/opentelemetry-proto.cmake#L350-L353

If BUILD_SHARED_LIBS is ON and the gRPC build is found to be STATIC.

Good point

owent avatar Oct 09 '24 13:10 owent

This issue was marked as stale due to lack of activity.

github-actions[bot] avatar Dec 13 '24 02:12 github-actions[bot]

CI is testing macos CMake builds with homebrew packages for third party dependencies including grpc and protobuf since v1.21.0. Closing this as resolved by #3220

dbarker avatar Nov 02 '25 17:11 dbarker