그 블로그 게시물은 매우 정확하지 않습니다.
내가 아는 한 C ++ ABI 변경 사항은 GCC의 모든 주요 릴리스 (즉, 첫 번째 또는 두 번째 버전 번호 구성 요소가 다른 버전)에 도입되었습니다.
사실이 아니다. GCC 3.4 이후 도입 된 유일한 C ++ ABI 변경 사항은 이전 버전과 호환됩니다. 즉, C ++ ABI가 거의 9 년 동안 안정적이었습니다.
설상가상으로, 대부분의 주요 Linux 배포판은 GCC 스냅 샷을 사용하거나 GCC 버전을 패치하므로 바이너리를 배포 할 때 처리 할 GCC 버전을 정확히 알 수 없습니다.
배포판의 패치 된 GCC 버전 간의 차이는 사소하고 ABI가 변경되지는 않습니다. 예를 들어 Fedora의 4.6.3 20120306 (Red Hat 4.6.3-2)은 업스트림 FSF 4.6.x 릴리스와 ABI 호환되며 거의 모든 4.6과 호환됩니다. x 다른 배포판에서.
GNU / Linux에서 GCC의 런타임 라이브러리는 ELF 심볼 버전 관리를 사용하므로 객체와 라이브러리에 필요한 심볼 버전을 쉽게 확인할 수 있습니다. libstdc++.so
이러한 심볼을 제공하는를 사용하면 작동합니다. 패치 된 버전이 약간 다른지 여부는 중요하지 않습니다. 배포판의 다른 버전에서.
그러나 이것이 작동한다면 C ++ 코드 (또는 C ++ 런타임 지원을 사용하는 코드)는 동적으로 링크 될 수 없습니다.
이것은 사실이 아닙니다.
즉, 정적으로 연결 libstdc++.a
것이 하나의 옵션입니다.
라이브러리를 동적으로로드하는 경우 (를 사용하여 dlopen
) 작동하지 않을 수있는 이유 는 종속 된 libstdc ++ 기호가 (정적으로) 링크 할 때 응용 프로그램에 필요하지 않았기 때문에 해당 기호가 실행 파일에 표시되지 않기 때문입니다. 이는 공유 라이브러리를 동적으로 링크하여 해결할 수 있습니다 libstdc++.so
(이에 의존하는 경우 어쨌든 수행 할 수있는 올바른 작업입니다.) ELF 기호 삽입은 실행 파일에있는 기호를 공유 라이브러리에서 사용하지만 다른 것은 사용하지 않음을 의미합니다. 실행 파일에있는 파일은 libstdc++.so
링크 된 모든 위치 에서 찾을 수 있습니다. 응용 프로그램이 사용하지 않는 경우dlopen
하지 않으면 그것에 대해 신경 쓸 필요가 없습니다.
또 다른 옵션 (그리고 내가 선호하는 옵션)은 libstdc++.so
애플리케이션과 함께 최신 버전을 배포하고 기본 시스템 앞에 있는지 확인하는 것입니다. libstdc++.so
이 작업 $LD_LIBRARY_PATH
은 실행시 환경 변수를 사용하여 동적 링커가 올바른 위치를 찾도록 강제함으로써 수행 할 수 있습니다. 시간 또는 RPATH
링크 시간에 실행 파일을 설정하여 . RPATH
응용 프로그램이 작동하도록 올바르게 설정된 환경에 의존하지 않기 때문에 사용하는 것을 선호합니다 . 응용 프로그램을 '-Wl,-rpath,$ORIGIN'
(셸이 확장하지 못하도록 작은 따옴표에 유의하십시오 $ORIGIN
) 연결하면 실행 파일은 런타임에 발견되는 실행 파일과 동일한 디렉토리에 문제가 해결됩니다. (또 다른 옵션은 실행 파일을 넣고 최신 libstdc ++. so를RPATH
으로 $ORIGIN
하는 자체 실행 파일과 같은 디렉토리에 공유 라이브러리를 찾기 위해 동적 링커를 알려줍니다. 새로운 것을 넣으면libstdc++.so
/some/path/bin/
/some/path/lib/
'-Wl,-rpath,$ORIGIN/../lib'
실행 파일과 관련된 또는 다른 고정 위치 와 연결 하고 RPATH를에 상대적으로 설정 $ORIGIN
)
-static-libstdc++
그냥 사용합니다 옵션-static