2012-05-30 2 views
33

현재 우분투 (12.04)에서 프로그램을 컴파일해야합니다. 이 프로그램은 이전 커널 (2.6.18)과 함께 CentOS를 사용하는 클러스터에서 실행되어야합니다. 불행히도 클러스터에서 직접 컴파일 할 수 없습니다. 방금 변경 사항없이 프로그램을 컴파일하고 복사하면 "kernel too old"라는 오류 메시지가 나타납니다.이전 libc (`GLIBC_2.14 '버전 없음)로 컴파일

내가 이해하는 방법은 커널 버전이 아니라 컴파일에 사용 된 libc 버전입니다. 그래서 나는 내 프로그램을 동적으로 libc를 클러스터에서 링크하고 다른 모든 것을 정적으로 링크하려고했다.

연구

는 SO에 이미이에 대한 많은 질문이있다 그러나 답변을 아무도 정말 나를 위해 일하지 않는다. 그래서 여기에 주제에 대한 내 연구입니다 :

  • This question
  • This question이 비슷하지만보다 전문이다 커널 너무 오래된 메시지에 대한 이유를 설명하고
  • 제안으로 정적으로 연결 아무런 답변이 없다가 here 작동하지 않았다 libc가 클러스터에서 너무 오래 되었기 때문입니다. 한 가지 대답은 이전 libc를 사용하여 빌드하는 것을 언급하지만이를 수행하는 방법은 설명하지 않습니다.
  • One way은 이전 OS를 실행하는 VM에서 컴파일해야합니다. 이것은 효과가 있지만 복잡합니다. 나는 또한 내가 복사

현재 상태를 you should not link libc statically

  • Apparently 그것이 is possible 옵션 -rpath와 다른 libc의 버전에 대한 컴파일 그러나 이것은 나를 위해 작동 (아래 참조)하지 않았다 읽기
  • 0 libc-2.5.so 디렉토리 /path/to/copied/libs

    • 에 클러스터에서 파일을 다음
    • libgcc_s.so.1
    • 된 libstdC++. so.6

    및 옵션 -nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s

    컴파일 된 바이너리에 LDD의 출력은 내가 '

    mybin: /path/to/copied/libs/libc.so.6: version `GLIBC_2.14' not found (required by mybin) 
    mybin: /path/to/copied/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mybin) 
    linux-vdso.so.1 => (0x00007ffff36bb000) 
    libc.so.6 => /path/to/copied/libs/libc.so.6 (0x00007fbe3789a000) 
    libstdc++.so.6 => /path/to/copied/libs/libstdc++.so.6 (0x00007fbe37599000) 
    libgcc_s.so.1 => /path/to/copied/libs/libgcc_s.so.1 (0x00007fbe3738b000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007fbe37bf3000) 
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbe37071000) 
    

    입니다 컴파일하고 그것은 올바른 경로를 사용하기 때문에 오류로 다소 혼란 스럽습니다. 클러스터의 libc)하지만 여전히 glibc 버전이 누락되었다고 불평합니다. 클러스터에서 ldd를 실행할 때 not a dynamic executable을 반환하고 바이너리를 실행하면 위에서 언급 한 두 가지 오류가 발생합니다. 또한 다른 라이브러리 (linux-vdso.so.1, ld-linux-x86-64.so.2 및 libm.so.6)가 포함 된 것처럼 보입니다. 뿐만 아니라 이전 버전을 사용해야합니까?

    그래서 지금은 두 가지 주요 질문은 :

    • 이도 올바른 접근 방법은 여기인가?
    • 예인 경우 : 이전 libc를 올바르게 연결하려면 어떻게합니까?

    답변

    10

    this 대답을 참조하십시오.

    은 여기에서도 올바른 접근 방식

    가 아니오 : 당신이 당신의 링크 명령처럼의 glibc 일치하지 않는 버전을 사용할 수 없습니다. crt0.old-linux.so에서 (시스템 설치) libc를 사용했지만 libc.so.6 (클러스터에서 복사) libc를 사용했습니다. 그것은 단지 작동하지 않을 것입니다.

    2

    -rpath가 DT_RPATH 태그를 설정하지만 libs와 거기에보고 링커 말하지 않습니다, 당신은 그것에 대해 -L를 원한다.