2013-09-25 1 views
2

다음은 제대로 링크 할 수없는 다소 간단한 응용 프로그램의 설정입니다. 기본적으로 단일 소스 파일 main.cpp, 정적 라이브러리 libbreakpad_client.a이있는 디렉토리 및 라이브러리의 헤더는 breakpad입니다. 여기 링커에서 정적 라이브러리에있는 심볼을 찾을 수없는 이유는 무엇입니까?

$ ls . 
main.cpp libs breakpad 
$ ls libs 
libbreakpad_client.a 

the Google Breakpad documentation에서 그대로 촬영 main.cpp에 대한 소스입니다. 내가 컴파일 할 때

#include "client/linux/handler/exception_handler.h" 

void crash() 
{ 
    volatile int* a = (int*)(NULL); 
    *a = 1; 
} 

static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) 
{ 
    printf("Dump path: %s\n", descriptor.path()); 
    return succeeded; 
} 

int main() 
{ 
    google_breakpad::MinidumpDescriptor descriptor("/tmp"); 
    google_breakpad::ExceptionHandler eh(descriptor, 0, dumpCallback, 0, true, -1); 
    crash(); 
    return 0; 
} 

하지만, 링커는 ExceptionHandler 생성자와 소멸자를 찾을 수 없습니다 뿌려줍니다.

$ g++ -Ibreakpad/src -lbreakpad_client -Llibs -o main main.cpp 
/tmp/ccDDGnQk.o: In function `main': 
main.cpp:(.text+0xed): undefined reference to `google_breakpad::ExceptionHandler::ExceptionHandler(google_breakpad::MinidumpDescriptor const&, bool (*)(void*), bool (*)(google_breakpad::MinidumpDescriptor const&, void*, bool), void*, bool, int)' 
main.cpp:(.text+0x106): undefined reference to `google_breakpad::ExceptionHandler::~ExceptionHandler()' 
collect2: error: ld returned 1 exit status 

그러나 우리는 libbreakpad_client.a에 존재 look at the symbols, 우리는

$ nm -an libs/libbreakpad_client.a | c++filt | grep "ExceptionHandler(" 
000000000000076c T google_breakpad::ExceptionHandler::ExceptionHandler(google_breakpad::MinidumpDescriptor const&, bool (*)(void*), bool (*)(google_breakpad::MinidumpDescriptor const&, void*, bool), void*, bool, int) 
000000000000076c T google_breakpad::ExceptionHandler::ExceptionHandler(google_breakpad::MinidumpDescriptor const&, bool (*)(void*), bool (*)(google_breakpad::MinidumpDescriptor const&, void*, bool), void*, bool, int) 
0000000000000972 T google_breakpad::ExceptionHandler::~ExceptionHandler() 
0000000000000972 T google_breakpad::ExceptionHandler::~ExceptionHandler() 

는 왜 링커는이이 undefined reference 것을 불평 않습니다 예상대로 기능이 정확히 존재하는 것을 볼 수 있다면?

답변

6

컴파일러에 대한 플래그 순서가 중요합니다. GCC documentation에서

$ g++ -Ibreakpad/src -Llibs -o main main.cpp -lbreakpad_client 

: 당신은 당신의 소스 파일 이름 후 -l 플래그 을 둘 필요가

그것은 명령에이 옵션을 쓰기 차이가; 링커는 라이브러리와 오브젝트 파일을 지정된 순서대로 검색하고 처리합니다. 따라서, foo.o -lz bar.o 검색 라이브러리 z 파일 후 foo.o하지만 전 bar.o. bar.oz의 함수를 나타내는 경우 해당 함수가로드되지 않을 수 있습니다.

3

링크 순서가 중요합니다! 라이브러리는 인수 목록에 나타나면 한 번만 검색됩니다. 이 시점에서 해결되지 않은 상징이 없다면 그 어떤 것도 그들과 함께 일어나지 않을 것입니다. 명령을

g++ -Ibreakpad/src -Llibs -o main main.cpp -lbreakpad_client 
으로 변경하십시오.
관련 문제