저는 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
gcc파일은 일반적으로
/usr/lib/gcc/
.
그런 다음 설치된 디렉터리의 libstdc++.so.6을 소프트 링크를 사용 /usr/lib
하거나 사용하여 연결합니다./usr/local/lib
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
답변3
첫째, 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/Linux의 "lib64"와 달리) 각각 32비트 또는 64비트를 컴파일하는지에 따라 다릅니다. Solaris의 GCC 컴파일러는 다중 아키텍처입니다.