저는 Solaris에서 첫 번째 C++ 프로그램을 실행하려고 합니다. 단순한 Hello World 프로그램입니다. 내가 달리려고 할 때. 오류가 발생했습니다 libstdc++.so.6:open failed:No such file or directory
. 물론 인터넷 검색을 해보니 환경 변수를 설정하면 이 문제를 해결할 수 있다는 것을 알았습니다.
export LD_LIBRARY_PATH=/usr/local/lib
다시 로그인한 후 이것이 영구적인 해결책이 아니라는 것을 발견했습니다. 나는 이것이 컴파일하는 동안 libstdc++.so.6을 연결하는 것과 관련이 있다고 생각합니다. 처음부터 제가 수행한 단계는 다음과 같습니다.
bash-3.2# gcc -c test.cpp
bash-3.2# gcc -o test test.o -lstdc++
bash-3.2# ./test
libstdc++.so.6:open failed:No such file or directory
bash-3.2# ldd test | grep not
libstdc++.so.6 => (file not found)
bash-3.2# /usr/ccs/bin/elfdump test | grep RUNPA
bash-3.2# find /usr -name libstdc++.so.6
/usr/local/lib/libstdc++.so.6
컴파일하는 동안 플래그 등을 놓쳤습니까? 프로그램을 실행할 때 어디를 볼지 알 수 있도록 소프트 링크를 어떻게 생성합니까?
제가 사용하고 있는 플랫폼은 다음과 같습니다.
bash-3.2# uname -a
SunOS ms-sparc8 5.8 Generic_108528-13 sun4u sparc SUNW,Sun-Blade-100
bash-3.2# gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls --disable-libgcj --enable-languages=c,c++
Thread model: posix
gcc version 3.3.2
답변1
Solaris 런타임 링커 검색 경로를 설정하는 가장 쉬운 방법은 을 사용하는 것입니다 crle
. 그러나 시스템이 중단되면 시스템을 쉽게 사용할 수 없게 만들 수 있으므로 이 작업을 수행할 때는 매우 주의해야 합니다! /usr/local/bin
링커 경로에 추가 :
# crle -u -l /usr/local/lib
이 작업을 완료한 후 crle
직접 전화를 걸어 새 검색 경로를 확인하세요.
또 다른 접근 방식은 경로를 바이너리 자체로 컴파일하는 것입니다.
$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++
링커 경로를 조정하지 않고도 바이너리가 다른 시스템에서 작동하므로 위의 옵션이 더 나은 옵션입니다.
답변2
문제는솔라리스로더가 라이브러리를 찾을 수 없습니다.
가장 좋은 방법은 LD_RUN_PATH
컴파일하는 동안 환경 변수를 다음 디렉터리로 설정하는 것입니다.libstdc++.so.xxxx(귀하의 버전 번호)은 아직 살아 있습니다. 이는 링커에게 런타임 시 이 디렉터리를 검색하도록 지시합니다.
LD_RUN_PATH
와 혼동하지 마시기 바랍니다LD_LIBRARY_PATH
. 후자는 런타임에 구문 분석되고LD_RUN_PATH
기본적으로 라이브러리 경로의 실행 파일로 컴파일되므로LD_LIBRARY_PATH
해당 라이브러리를 찾는 데 설정이 필요하지 않습니다.
다른 모든 방법이 실패하면 언제든지 환경 변수를 적절하게 설정하는 래퍼 셸 스크립트에서 프로그램을 실행할 수 있습니다 LD_LIBRARY_PATH
.
이것이 중요한 포인트입니다,
설정LD_LIBRARY_PATH, 포함되지 않은 경우
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
걸프 협력 협의회파일은 일반적으로
/usr/lib/gcc/
.
그런 다음 설치 디렉터리의 libstdc++.so.6을 링크하거나 /usr/lib
소프트 /usr/local/lib
링크를 사용합니다.
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
답변3
우선, crle을 사용할 필요가 없습니다. (당신이 하고 있는 일을 정말로 이해하지 않는 한, 그것을 멀리하세요. 저를 믿으세요. crle을 사용할 때 엄청난 런타임 오류가 발생하게 될 것입니다.)
둘째, LD_LIBRARY_PATH(대부분의 경우)를 설정하거나 /usr에 있는 타사 라이브러리를 심볼릭 링크할 필요가 없습니다.
mjturner의 제안을 따르고 컴파일할 때 gcc에 올바른 런타임 경로를 제공하십시오.
추신: C++ 코드는 g++로 컴파일되어야 합니다.
링크:
http://notes.theorbis.net/2010/01/how-to-screw-up-solaris-with-crle.html http://prefetch.net/articles/linkers.badldlibrary.html
답변4
g++ 프런트 엔드를 사용하면 C++ 코드를 libstdc++ 라이브러리와 올바르게 연결하는 방법을 알 수 있습니다. 이는 특히 솔라리스의 경우에 해당됩니다.
무엇을 하든지 어떤 상황에서도 LD_RUN_PATH 또는 LD_LIBRARY_PATH를 사용하지 마십시오. 이러한 변수는 공유 객체 라이브러리 개발자가 최종 링크가 아닌 디버깅을 돕기 위해 사용하기 위한 것입니다. 이를 사용하면 공유 개체 라이브러리의 다른 버전에서 기호가 삽입되고 위 삽입으로 인해 런타임에 어떤 기호가 사용되는지 알 수 없기 때문에 디버깅하기 어려운 잠재적인 충돌이 발생할 수 있습니다.
항상 g++ 프런트엔드를 통해 연결하세요. 추가 RPATH 정보를 링크 편집기에 전달해야 하는 경우 올바른 접근 방식은 g++ -Wl,-R/path/to/lib 또는 g++ -m64 -Wl,-R/path/to/lib/64입니다(다음과 같이). GNU/ "lib64"는 Linux에서 다릅니다. 32비트 또는 64비트용으로 컴파일하는지에 따라 다릅니다. Solaris의 GCC 컴파일러는 다중 아키텍처입니다.