32비트 모드에서 gcc 원자적 작업을 컴파일할 때 링크 오류가 발생했습니다.
문제
다음 프로그램이 있습니다.
~/test> cat test.cc
int main()
{
int i = 3;
int j = __sync_add_and_fetch(&i, 1);
return 0;
}
저는 다중 CPU 64비트 Intel 시스템에서 실행되는 Linux에서 GCC 4.2.2를 사용하여 이 프로그램을 컴파일하고 있습니다.
~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux
64비트 모드에서 프로그램을 컴파일하면 정상적으로 컴파일되고 링크됩니다.
~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>
32비트 모드로 컴파일하면 다음과 같은 오류가 발생합니다.
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test>
실제로 32비트 프로세서에서 실행하지는 않지만 일부 32비트 라이브러리와 연결하려면 32비트 실행 파일이 필요합니다.
내 두 가지 질문은 다음과 같습니다
32비트 모드에서 컴파일할 때 링크 오류가 발생하는 이유는 무엇입니까?
32비트 라이브러리와 연결하면서 프로그램을 컴파일하고 연결하는 방법이 있습니까?
해결책
로부터 Atomic 내장의 GCC 페이지:
모든 대상 프로세서에서 모든 작업이 지원되는 것은 아닙니다.대상 프로세서에서 특정 작업을 구현할 수없는 경우 경고가 생성되고 외부 기능이 생성됩니다.외부 함수는 내장과 동일한 이름을 갖고 추가 접미사`_n '이있는 경우 N은 데이터 유형의 크기입니다.
컴파일러 출력으로 판단하면 다음과 같습니다. __sync_add_and_fetch_4
, 이게 무슨 일이야.어떤 이유로 GCC가 외부 기능을 제대로 생성하지 못합니다.
이것이 32비트 모드에서만 오류가 발생하는 이유일 가능성이 높습니다. 64비트 모드로 컴파일하면 프로세서에 더 가깝게 컴파일됩니다.32비트용으로 컴파일할 때 기본적으로 해당 기능을 지원하지 않는 일반 아치(예: i386)를 사용하고 있을 수 있습니다.-mcpu를 통해 칩 제품군(Xeon, Core 2 등)에 대한 특정 아키텍처를 지정하고 작동하는지 확인하세요.
그렇지 않다면 왜 GCC가 생성해야 하는 적절한 함수를 포함하지 않는지 알아내야 합니다.
다른 팁
Dan Udey의 답변은 가까웠으며 실제로 실제 해결책을 찾을 수있을 정도로 가까웠습니다.
Man Page에 따르면 "-mcpu"는 "-mtune"에 대한 더 이상 사용되지 않은 동의어이며 "특정 CPU에 대해 최적화하지만 여전히 최적의 CPU에서 실행됩니다." 나는 이것을 시도했지만 문제를 해결하지 못했습니다.
그러나 "-march ="는 "특정 CPU에 대한 코드를 생성하고 구형 CPU에서 실행하지 않음"을 의미합니다. 이것을 시도했을 때 문제가 해결되었습니다. i486의 CPU를 지정하거나 링크 오류를 제거했습니다.
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc
~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc