2016-08-02 3 views
0

Я работаю на Mac. Я установил libprotobuf с brew install protobuf --c++11.Неопределенная ссылка при соединении protobuf

17:51 $ brew info protobuf 
protobuf: stable 2.6.1 (bottled), devel 3.0.0-beta-4, HEAD 
Protocol buffers (Google's data interchange format) 
https://github.com/google/protobuf/ 
/usr/local/Cellar/protobuf/2.6.1 (149 files, 7.0M) * 
    Built from source on 2016-08-02 at 17:42:15 with: --c++11 

libprotobuf.dylib живет в /usr/local/Cellar/protobuf/2.6.1/lib.

Я написал следующее фиктивного приложения в надежде вызвать this constructor:

// test.cc 
#include <string> 
#include <google/protobuf/io/coded_stream.h> 
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> 

int main() { 
    std::string s{"hello"}; 
    google::protobuf::io::StringOutputStream sos(&s); 
} 

Когда я скомпилировать приложение, я получаю неопределенную ссылочную ошибку:

17:55 $ g++ -L/usr/local/Cellar/protobuf/2.6.1/lib -std=c++14 test.cc -lprotobuf 
Undefined symbols for architecture x86_64: 
    "google::protobuf::io::StringOutputStream::StringOutputStream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)", referenced from: 
     _main in ccyQlDM5.o 
ld: symbol(s) not found for architecture x86_64 
collect2: error: ld returned 1 exit status 

Когда я проверяю .dylib для StringOutputStream, это немного отвратительно.

17:56 $ nm /usr/local/Cellar/protobuf/2.6.1/lib/libprotobuf.dylib | c++filt | grep "StringOutputStream(std::" 
000000000000e3ac T google::protobuf::io::StringOutputStream::StringOutputStream(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) 
000000000000e398 T google::protobuf::io::StringOutputStream::StringOutputStream(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) 

Почему basic_string пространства имен с префиксом ::__1 в моем списке символов для этого .dylib? Как я могу это исправить?

Если это не проблема (возможно, артефакт непонятного), почему я все еще получаю неопределенную ссылку на вызов конструктора, который, как мне известно, определяется?

Я использую gcc 5.3.0 для компиляции test.cc.

+2

Не имеет ли GCC 5 другой тип строки, кроме GCC 4? Вам, вероятно, нужна библиотека, скомпилированная с помощью GCC 5. –

+0

@KerrekSB Библиотека была построена из источника ('Построен из источника ... с: --C++ 11'). Считаете ли вы, что стоит избегать «заваривания» вообще и пытаться клонировать автономное репо и строить это? – erip

+2

Версия для пива была построена с помощью clang, по умолчанию используется -stdlib = libC++. Gcc по умолчанию - -stdlib = libstdC++. Эти два несовместимы. –

ответ

0

Как упоминалось в комментариях, Homebrew строился с clang вместо g++.

Я удалил protobuf, установленный brew, извлек и построил источник, скопировал новый .dylib в /usr/local/lib, и он отлично работал.

+1

Я должен спросить ... почему бы не использовать clang Xcode при создании на Mac? –

+1

@ RichardHodges В конце концов, это будет Linux. Попытка «черного ящика» - как можно больше, и просто сосредоточиться на «реальных проблемах» (например, связывание ..) :) – erip

+1

@RichardHodges И если ничего другого, педагогические причины для меня достаточно хороши. – erip

Смежные вопросы