2009-07-29 7 views
22

, 프로그램은 "foo는 소위"인쇄해야합니다 : 프로그램이 다음과 같이 컴파일__attribute __ ((constructor))가 정적 라이브러리에서 작동하지 않는 이유는 무엇입니까? 다음 예에서

// foo.c 
#include <stdio.h> 

__attribute__((constructor)) void foo() 
{ 
    printf("foo called\n"); 
} 

// main.c 
int main() 
{ 
    return 0; 
} 

경우, 작동 :

gcc -o test main.c foo.c 

그러나, foo.c를가로 컴파일 된 경우 정적 라이브러리 인 경우, 프로그램은 아무것도 인쇄하지 않습니다.

gcc -c main.c 
gcc -c foo.c 
as rcs foo.a foo.o 
gcc -o test foo.a main.o 

왜 이런 일이 발생합니까?

+0

왜 downvotes? 잘못된 것이 있습니까? –

+0

잘 모르시겠습니까? (나 아니 었나요?)하지만 누군가가 당신의 질문에 너무 빨리 답하는 것을 예외로 생각했을까요? – DaveR

+1

흠, 나는 단지 명백하지 않은 문제에 대한 유용한 참조를 사이트에 추가하기를 원했습니다. FAQ는 자신의 질문에 대답하는 것이 좋은 것이라고 지적합니다 (사실 첫 번째 섹션에 있습니다). –

답변

13

링커는 main.o의 내용을 참조하지 않으므로 foo.a의 코드를 최종 프로그램에 포함하지 않습니다. main.c은 다음과 같이 다시 작성하는 경우, 프로그램이 작동합니다

는 또한
//main.c 

void foo(); 

int main() 
{ 
    void (*f)() = foo; 
    return 0; 
} 

, 정적 라이브러리로 컴파일 할 때, GCC (또는 링커)의 인수의 순서가 중요하다 : 라이브러리는 객체 후 와야합니다 그것을 참조하십시오.

gcc -o test main.o foo.a 
2

언급 한대로 아카이브에서 참조되지 않은 기호는 출력 바이너리로 지정하지 않습니다. 링커는 기본적으로이 기호를 삭제하기 때문입니다. foo.a에서 모든 심볼이 포함되기 때문에

gcc -c main.c 
gcc -c foo.c 
ar rcs foo.a foo.o 
gcc -o test -Wl,--whole-archive foo.a -Wl,--no-whole-archive main.o 

이, 부풀어 진 발생할 수 있습니다 : 정적 라이브러리와 링크 할 때

은 링커에 대한 --whole-archive/ --no-whole-archive 옵션과 같이 사용할 수 있으며,이 동작을 재정의하려면 링커에 의해 출력으로 보내지 만 때로는 그것이 정당화됩니다.