我正在嘗試在 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
來查找其庫。
如果所有其他方法都失敗,您始終可以從適當設定環境變數的包裝器 shell 腳本執行程式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 (除非你真的明白你在做什麼,否則遠離它;相信我,當你使用錯誤時,你會因為瘋狂的運行時錯誤而把自己鎖在外面)
其次,不需要設定 LD_LIBRARY_PATH(大多數情況下),也不需要在 /usr 中符號連結任何第三方函式庫
只需按照 mjturner 的建議進行操作並在編譯時為 gcc 提供正確的運行時路徑即可
PS: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++ 函式庫。對於 Solaris 來說尤其如此。
無論您做什麼,在任何情況下都不要使用 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 編譯器是多架構的。