Skip to content

Unresolved external symbol TracerProviderFactory::Create #3014

@nefarius

Description

@nefarius

Describe your environment

After upgrading from 1.14.x to 1.16.0 and 1.16.1 building the same code fails with a linker error, not finding TracerProviderFactory::Create:

error LNK2001: unresolved external symbol "public: static class std::unique_ptr<class opentelemetry::v1::sdk::logs::LoggerProvider,struct std::default_delete<class opentelemetry::v1::sdk::logs::LoggerProvider> > __cdecl opentelemetry::v1::sdk::logs::LoggerProviderFactory::Create(class std::unique_ptr<class opentelemetry::v1::sdk::logs::LogRecordProcessor,struct std::default_delete<class opentelemetry::v1::sdk::logs::LogRecordProcessor> > &&,class opentelemetry::v1::sdk::resource::Resource const &)" (?Create@LoggerProviderFactory@logs@sdk@v1@opentelemetry@@SA?AV?$unique_ptr@VLoggerProvider@logs@sdk@v1@opentelemetry@@U?$default_delete@VLoggerProvider@logs@sdk@v1@opentelemetry@@@std@@@std@@$$QEAV?$unique_ptr@VLogRecordProcessor@logs@sdk@v1@opentelemetry@@U?$default_delete@VLogRecordProcessor@logs@sdk@v1@opentelemetry@@@std@@@7@AEBVResource@resource@345@@Z)
error LNK2001: unresolved external symbol "public: static class std::unique_ptr<class opentelemetry::v1::sdk::trace::TracerProvider,struct std::default_delete<class opentelemetry::v1::sdk::trace::TracerProvider> > __cdecl opentelemetry::v1::sdk::trace::TracerProviderFactory::Create(class std::unique_ptr<class opentelemetry::v1::sdk::trace::SpanProcessor,struct std::default_delete<class opentelemetry::v1::sdk::trace::SpanProcessor> >,class opentelemetry::v1::sdk::resource::Resource const &)" (?Create@TracerProviderFactory@trace@sdk@v1@opentelemetry@@SA?AV?$unique_ptr@VTracerProvider@trace@sdk@v1@opentelemetry@@U?$default_delete@VTracerProvider@trace@sdk@v1@opentelemetry@@@std@@@std@@V?$unique_ptr@VSpanProcessor@trace@sdk@v1@opentelemetry@@U?$default_delete@VSpanProcessor@trace@sdk@v1@opentelemetry@@@std@@@7@AEBVResource@resource@345@@Z)

Steps to reproduce

OTEL CPP is consumed via vcpkg manifest:

{
  ...
  "dependencies": [
    { "name": "abseil" },
    {
      "name": "opentelemetry-cpp",
      "features": [ "otlp-grpc" ]
    }
  ]
}

Project is a simple Windows DLL, OTEL CPP is statically linked.

Used includes:

#define HAVE_ABSEIL // fixes redefinitions of absl types
// gRPC exporter
#include <opentelemetry/exporters/otlp/otlp_grpc_exporter_factory.h>
#include <opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h>

#include <opentelemetry/sdk/trace/processor.h>
#include <opentelemetry/sdk/trace/simple_processor_factory.h>
#include <opentelemetry/sdk/trace/tracer_provider_factory.h>
#include <opentelemetry/sdk/resource/resource.h>
#include <opentelemetry/sdk/resource/semantic_conventions.h>
#include <opentelemetry/trace/provider.h>
#include <opentelemetry/trace/tracer_provider.h>

// gRPC exporter
#include <opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter_factory.h>
#include <opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter_options.h>

#include <opentelemetry/logs/provider.h>
#include <opentelemetry/sdk/common/global_log_handler.h>
#include <opentelemetry/sdk/logs/logger_provider_factory.h>
#include <opentelemetry/sdk/logs/logger_provider.h>
#include <opentelemetry/sdk/logs/processor.h>
#include <opentelemetry/sdk/logs/simple_log_record_processor_factory.h>

namespace trace     = opentelemetry::trace;
namespace nostd     = opentelemetry::nostd;
namespace otlp      = opentelemetry::exporter::otlp;
namespace logs_sdk  = opentelemetry::sdk::logs;
namespace logs      = opentelemetry::logs;
namespace trace_sdk = opentelemetry::sdk::trace;

Relevant code snippet:

//
// Set up tracing
// 

opentelemetry::sdk::resource::ResourceAttributes resourceAttributes = opentelemetry::sdk::resource::ResourceAttributes{
	{ opentelemetry::sdk::resource::SemanticConventions::kServiceName, TRACER_NAME }
};

opentelemetry::sdk::resource::Resource resource = opentelemetry::sdk::resource::Resource::Create(resourceAttributes);
std::unique_ptr<trace_sdk::SpanExporter> traceExporter = otlp::OtlpGrpcExporterFactory::Create();
std::unique_ptr<trace_sdk::SpanProcessor> traceProcessor = trace_sdk::SimpleSpanProcessorFactory::Create(
	std::move(traceExporter));
std::shared_ptr<trace_sdk::TracerProvider> traceProvider = trace_sdk::TracerProviderFactory::Create(
	std::move(traceProcessor), resource);

std::shared_ptr<trace::TracerProvider> api_provider = traceProvider;
trace::Provider::SetTracerProvider(api_provider);

//
// Set up logger
// 

std::unique_ptr<logs_sdk::LogRecordExporter> loggerExporter = otlp::OtlpGrpcLogRecordExporterFactory::Create();
std::unique_ptr<logs_sdk::LogRecordProcessor> loggerProcessor = logs_sdk::SimpleLogRecordProcessorFactory::Create(
	std::move(loggerExporter));
std::shared_ptr<logs_sdk::LoggerProvider> loggerProvider = logs_sdk::LoggerProviderFactory::Create(
	std::move(loggerProcessor), resource);

std::shared_ptr<logs::LoggerProvider> l_api_provider = loggerProvider;
logs::Provider::SetLoggerProvider(l_api_provider); 

What is the expected behavior?

Solution should build fine, I applied the migration path mentioned here but nothing changes.

What is the actual behavior?

error LNK2001: unresolved external symbol "public: static class std::unique_ptr<class opentelemetry::v1::sdk::logs::LoggerProvider,struct std::default_delete<class opentelemetry::v1::sdk::logs::LoggerProvider> > __cdecl opentelemetry::v1::sdk::logs::LoggerProviderFactory::Create(class std::unique_ptr<class opentelemetry::v1::sdk::logs::LogRecordProcessor,struct std::default_delete<class opentelemetry::v1::sdk::logs::LogRecordProcessor> > &&,class opentelemetry::v1::sdk::resource::Resource const &)" (?Create@LoggerProviderFactory@logs@sdk@v1@opentelemetry@@SA?AV?$unique_ptr@VLoggerProvider@logs@sdk@v1@opentelemetry@@U?$default_delete@VLoggerProvider@logs@sdk@v1@opentelemetry@@@std@@@std@@$$QEAV?$unique_ptr@VLogRecordProcessor@logs@sdk@v1@opentelemetry@@U?$default_delete@VLogRecordProcessor@logs@sdk@v1@opentelemetry@@@std@@@7@AEBVResource@resource@345@@Z)
error LNK2001: unresolved external symbol "public: static class std::unique_ptr<class opentelemetry::v1::sdk::trace::TracerProvider,struct std::default_delete<class opentelemetry::v1::sdk::trace::TracerProvider> > __cdecl opentelemetry::v1::sdk::trace::TracerProviderFactory::Create(class std::unique_ptr<class opentelemetry::v1::sdk::trace::SpanProcessor,struct std::default_delete<class opentelemetry::v1::sdk::trace::SpanProcessor> >,class opentelemetry::v1::sdk::resource::Resource const &)" (?Create@TracerProviderFactory@trace@sdk@v1@opentelemetry@@SA?AV?$unique_ptr@VTracerProvider@trace@sdk@v1@opentelemetry@@U?$default_delete@VTracerProvider@trace@sdk@v1@opentelemetry@@@std@@@std@@V?$unique_ptr@VSpanProcessor@trace@sdk@v1@opentelemetry@@U?$default_delete@VSpanProcessor@trace@sdk@v1@opentelemetry@@@std@@@7@AEBVResource@resource@345@@Z)

Additional context

Neither the v1.14.x compatible nor the upgraded (factory deprecation) variant works under 1.16.x, I skipped 1.15 so IDK the behavior there.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdo-not-staletriage/acceptedIndicates an issue or PR is ready to be actively worked on.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions