2014-10-02 2 views
3

GCC와 동적 및 정적 링크를 사용하여 매우 단순한 (hello world처럼 간단한) C 프로그램을 컴파일하려고합니다. 나는 이것을 일반적으로하는 법을 알고 싶다. 그래서 나의 최소한의 테스트 예제는 단순히 libc를 정적과 libm으로 동적으로 연결하려고 시도하고있다.GCC에서 부분적으로 정적 인 부분적으로 동적 인 링크하기

내가 건너 한 적어도 동일한 주제에 대한 다른 질문을 다음

GCC: static linking only some libraries

Static link of shared library function in gcc

거기에 같은 -Wl, -Bstatic를 사용하여 같은 것들을 제안에 대한 답변의 일부와 -Wl, -Bdynamic : 각각 정적 및 동적 라이브러리를 지정합니다. 또한 링크 된 정적 라이브러리의 전체 경로를 지정하기 만하면됩니다.

나는 여러 가지 제안과 그 변형을 시도해 보았습니다. 나는 그것이 나에게주는 오류 메시지를 이해하지 못한다. 나는 PIE가 무엇인지는 알고 있지만, 내가하려고하는 것에 그것이 어떻게 관련되어 있는지 보지 못한다. 다음 그러나

$ gcc test.c -lm 
$ gcc -static test.c -lm 

: 여기

는 어떤 시도에 실패 있습니다 : 인수없이 바로 컴파일

$ gcc test.c /usr/lib64/libc.a 
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie 
urned 1 exit status 
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s 
collect2: error: ld returned 1 exit status 
$ gcc -Wl,-Bdynamic -lm -Wl,-Bstatic -lc test.c 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s 
collect2: error: ld returned 1 exit status 
$ gcc -Wl,-Bstatic -lc -Wl,-Bdynamic -lm test.c 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie 
collect2: error: ld returned 1 exit status 

을하고 -static 작업 벌금,하지만 난 부분 정적 컴파일이 필요 또한 실패합니다 :

$ gcc test.c /usr/lib64/libc.a /usr/lib64/libm.a 

이 게시물에 유사한 오류 건너했습니다

C++ Statically linked shared library

답변이 내 문제에 적용하지 못하는 것 같습니다 그러나.

내가 컴파일하기 위해 노력하고있어이 프로그램은 단순히 (TEST.C로)입니다 :

#include <stdio.h> 
#include <math.h> 

int main(int argc, char **argv) 
{ 
    int i = 0; 

    for(i = 0; i < 65535; i++) { 
      printf("%f\n", sinf(i)); 
      printf("%f\n", cosf(i)); 
      printf("%f\n", tanf(i)); 
      printf("%f\n", sqrtf(i)); 
    } 


    return 0; 
} 

편집 : 프로그램이 실제로 libm의, 그렇지 않으면 연결 시도가 거짓을 줄 수도 필요로 할만큼 복잡하셔야합니다 libm이 정말로 필요하지 않은 경우에 긍정적입니다. 필자의 원래 test.c 예제에서는 sinf()를 상수 값에만 사용하여 컴파일러가 sinf() 호출을 완벽하게 최적화하도록했습니다.

내가 사용 :

$ gcc --version 
gcc (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3 
+0

gcc의 권장 사항 (오류 메시지 참조)을 수행하려고 시도 했습니까? – Ashalynd

+0

-fPIE와 -pie는 나에게 아무런 의미가 없습니다. 어떤 경우에도 PIE로 컴파일하고 싶지는 않습니다. – AttributedTensorField

답변

3

(가) 나를 위해 일한 다음

ln -s `gcc -print-file-name=libc.a` 
gcc -static-libgcc -L. -lc test.c 

다음 ldd a.out을 제공합니다

not a dynamic executable 

편집 :

영업 이익은 연결하고자하는 하나의 리 brary는 동적이고 다른 하나는 정적입니다. 그는 libc을 정적으로 연결하고 libm을 동적으로 연결하는 예가 있습니다. 그 특별한 경우 나는 성취 할 수 없었습니다. 그러나 역으로, 즉 libc을 동적으로 연결하고 libm을 정적으로 연결하는 것이 가능합니다.

ln -s `gcc -print-file-name=libm.a` 
gcc test.c -L. -lm 

ldd a.out 링크 순서가 gcc -L. -lm test.c이 작동하지 않는 matters.e.g 것을

libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x41960000) 
/lib/ld-linux.so.2 (0x4193d000) 

참고를 제공합니다.

다른 라이브러리에서도 마찬가지입니다. 예 : gomp

gcc -fopenmp test.c 

lddd는 libgomp.so.1입니다. 우리는 libgomp.so.1을 표시하지 않습니다 지금이

ln -s `gcc -print-file-name=libgomp.a` 
gcc -L. -fopenmp test.c 

ldd a.out처럼 정적으로 연결할 수 있습니다. 그러나이 경우 pthreads은 여전히 ​​동적으로 링크되어 있습니다. pthreads를 정적으로 연결하려면 requires that libc be linked statically as well.

+0

정적 바이너리를 컴파일 한 것처럼 보입니다. 목표는 동적으로 링크 된 다른 라이브러리를 가지고있는 동안 정적으로 링크 된 라이브러리가있는 2 진 파일을 컴파일하는 것입니다. 예 : libc가 정적으로 링크되고 libm이 동적으로 링크되는 원래의 질문 에서처럼. 귀하의 예제 에서이 a.out 파일은 정적입니다. – AttributedTensorField

+0

@AttributedTensorField, 자세한 내용으로 답변을 업데이트했습니다. 'libc'를 정적으로'libm'에 동적으로 링크하는 방법을 모르겠습니다. 그러나 그 반대가 가능합니다. 나는 일반적으로'ligc'가 동적으로 링크되어있는 한 다른 라이브러리를 정적 또는 동적으로 링크한다고 생각합니다. 'pthreads'는 하나의 예외입니다. 예를 들어 링크하면 어떻게 될지 잘 모르겠습니다. gnu libc 대신 libm을 사용하는 musl libc. –

+0

예제에 포함 된 소스 코드에 문제가 있습니다. sinf()가 상수 인수와 함께 호출되기 때문에 컴파일러는 컴파일 전에 결과를 계산하고 최적화합니다. 그러므로 libm은 필요하지 않습니다. 내가 libm을 실제로 요구하도록 소스를 변경할 때 컴파일하려고하면 다음과 같은 에러가 발생합니다 : test.c :(.text + 0x28) : 'sinf'에 대한 정의되지 않은 참조; 나는 적절한 코드 예제로 질문을 업데이트 할 것이다. – AttributedTensorField