2011-09-06 4 views
0

중복 식별자는 아카이버 및 링커에서 단순히 무시됩니다. 소스 또는 객체 파일이 gcc에 직접 전달되는 경우에만 탐지되며 여러 정의에는 오류가있는 것으로 간주됩니다. 뿐만 아니라해야합니다. 아카이버/링커는 단순히 그것들을 무시하고 우리는 오직 하나의 식별자로 끝난다. 오브젝트 파일 또는 라이브러리가 전달되는 순서에 따라 달라집니다. 아래는이를 증명하는 스크립트입니다.gcc : 객체 파일 또는 라이브러리의 중복 식별자

아카이버/링커가 오류라고 생각할 수있는 방법이 있습니까? 아니면 이것을 처리 할 다른 도구가 있습니까?

#!/bin/sh 

dir=$(mktemp -d) 
echo "Using temporary directory: $dir" 
echo 
cd "$dir" 

create_lib() 
{ 
    lib=$1 
    shift 
    rm -f $lib 
    ar r $lib "[email protected]" 2>/dev/null 
} 

make_file() 
{ 
    base=file$1 
    cat >$base.c <<-EOF 
    int f() 
    { 
     return $1; 
    } 
    EOF 

    gcc $base.c -o $base.o -c 

    create_lib lib$base.a $base.o 
} 

make_file 1 
make_file 2 

cat >main.c <<EOF 
int main() 
{ 
    extern int f(); 
    return f(); 
} 
EOF 

gcc main.c -omain.o -c 

cat <<EOF 
1. Passing duplicate functions to archiver in different order 
    produces no error, but different result: 
EOF 

create_lib libfile.a file1.o file2.o 
gcc main.o libfile.a -omain 
(echo -n "ar file1.o file2.o: "; ./main; echo $?) 

create_lib libfile.a file2.o file1.o 
gcc main.o libfile.a -omain 
(echo -n "ar file2.o file1.o: "; ./main; echo $?) 

echo 

cat <<EOF 
2. Passing duplicate libraries to linker in different order 
    produces no error, but different result: 
EOF 

gcc main.o libfile2.a libfile1.a -omain 
(echo -n "gcc libfile2.a libfile1.a: "; ./main; echo $?) 

gcc main.o libfile1.a libfile2.a -omain 
(echo -n "gcc libfile1.a libfile2.a: "; ./main; echo $?) 

샘플 출력 :

Using temporary directory: /tmp/tmp.AaXzxGcSdd 

1. Passing duplicate functions to archiver in different order 
    produces no error, but different result: 
ar file1.o file2.o: 1 
ar file2.o file1.o: 2 

2. Passing duplicate libraries to linker in different order 
    produces no error, but different result: 
gcc libfile2.a libfile1.a: 2 
gcc libfile1.a libfile2.a: 1 

답변

0

나는 당신이 링커에 전달 된 --whole-archive 옵션을 사용하여 원하는 동작을 얻을 수 있다고 생각합니다. 는 GNU LD의 문서에서 :

--whole-archive 옵션 다음 명령 줄에 언급 된 각 아카이브에 대한

--whole-archive

는 의 링크보다는에 대한 아카이브를 검색을 아카이브에있는 모든 오브젝트 파일을 포함 필수 개체 파일. 일반적으로 보관 파일을 공유 된 라이브러리로 변환하여 결과적으로 공유 된 라이브러리에 모든 개체가 포함되도록합니다. 이 옵션은 두 번 이상 사용될 수 있습니다. GCC에서이 옵션을 사용하는 경우

두 노트 : 첫째, GCC는이 옵션에 대한 을 모르는, 그래서 당신은 -Wl,-whole-archive을 사용해야합니다. 둘째, gcc가 자신의 링크 목록에 보관 파일 목록을 추가하기 때문에 귀하의 목록 뒤에 -Wl,-no-whole-archive을 사용하는 것을 잊지 마십시오. 이 플래그가 해당 파일에도 영향을 미치지 않도록 할 수 있습니다.

+0

팁 주셔서 감사합니다. 그래도 내 테스트에는 도움이되지 않는 것 같습니다. – drizzd

관련 문제