정적 라이브러리에서 __attribute__((구성자))가 작동하지 않는 이유는 무엇입니까?
다음 예제에서 프로그램은 인쇄해야 합니다."foo called\n"
:
// 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
그러나 fo.c가 정적 라이브러리로 컴파일되면 프로그램은 아무것도 인쇄하지 않습니다.
gcc -c main.c
gcc -c foo.c
as rcs foo.a foo.o
gcc -o test foo.a main.o
왜 이런 일이 일어날까요?
링커는 fo.a의 코드를 포함하지 않습니다. 왜냐하면 main.o의 어떤 것도 그것을 참조하지 않기 때문입니다. 만약main.c
다음과 같이 다시 작성되며 프로그램이 작동합니다.
//main.c
void foo();
int main()
{
void (*f)() = foo;
return 0;
}
또한 정적 라이브러리로 컴파일할 때 gcc(또는 링커)에 대한 인수 순서가 중요합니다. 라이브러리는 참조하는 개체 뒤에 와야 합니다.
gcc -o test main.o foo.a
명시된 것처럼, 아카이브의 참조되지 않은 기호는 기본적으로 링커가 이 기호들을 버리기 때문에 출력 바이너리에 들어가지 않습니다.
정적 라이브러리와 링크할 때 이 동작을 재정의하려면,--whole-archive
/--no-whole-archive
링커에 대한 옵션은 다음과 같이 사용할 수 있습니다.
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
이는 모든 기호가 다음과 같으므로 팽창된 이진법으로 이어질 수 있습니다.foo.a
링커에 의해 출력에 포함되지만 정당화되는 경우도 있습니다.
언급URL : https://stackoverflow.com/questions/1202494/why-doesnt-attribute-constructor-work-in-a-static-library
'programing' 카테고리의 다른 글
굵은 문자열 부분 (0) | 2023.10.04 |
---|---|
자바스크립트에서 콜백 함수에 대해 더 잘 이해하기 (0) | 2023.10.04 |
중첩된 파이프라인에서 상위 수준 $_ 파이프라인 변수에 액세스하려면 어떻게 해야 합니까? (0) | 2023.10.04 |
관계형 데이터베이스 대신 문서 기반 데이터베이스를 사용해야 하는 이유는 무엇입니까? (0) | 2023.10.04 |
컴파일된 TypeScript의 출력 폴더 (0) | 2023.10.04 |