2011-03-31 105 views
0

我正在一臺沒有root權限的計算機上進行一些C編程。我編譯了一些我正在鏈接的共享庫,但是因爲我無法將這些庫安裝在典型的位置(/usr/local/lib),所以每次編譯和運行時都必須明確指定庫的位置。編譯時,這意味着將-L標誌添加到gcc命令中,但對於程序執行而言,這更令人討厭。我必須在每個會話中將非標準目錄添加到LD_LIBRARY_PATH,或者我必須將LD_PRELOAD=/path/to/libs添加到execute命令的開頭。替代LD_PRELOAD或LD_LIBRARY_PATH

有沒有更好的方式在我沒有root權限的機器上執行此操作?

順便說一句,該機器運行的是Red Hat 4.1。

+0

您可以使用'-rpath'或類似選項來硬編碼二進制文件中庫的路徑。 – 2011-03-31 17:22:33

+1

等等.. Red Hat 4.1!?!在這種情況下,您只需將其根目錄並安裝系統範圍的庫... – 2011-03-31 17:23:17

回答

2

有幾種解決方案,從更好地惡化:

  1. 使用$ORIGIN,例如gcc main.o -L../lib -lfoo -Wl,-rpath='$ORIGIN'/../lib
  2. 使用目標RPATH,例如, gcc main.o -L../LIB -lfoo -Wl,-rpath=/home/user/lib
  3. LD_LIBRARY_PATH.bashrc.profile

解決方案1,您可以在任何地方安裝二進制,只要你移動的二進制和庫一起,例如my-app/bin/a.out和my-app/lib/{needed-shared-libs} .so。它還允許應用程序的多個版本及其共享庫的集合。

解決方案2工作正常,如果你只需要一套共享庫,並且從不希望移動它們。

解決方案3會影響您運行的每個應用程序,並可能導致其中一些綁定到您的共享庫而不是系統庫。這可能會導致他們崩潰,未解決的符號失敗,或導致您其他的痛苦。要加劇,這個問題只會發生在你和其他人身上,所以你很難得到幫助。

1

您可以將環境變量添加到您的.bashrc(或登錄時您的shell源代碼的任何文件)。

+0

將LD_LIBRARY_PATH添加到您的.bashrc是不合適的,因爲它只與單個應用程序相關。當OP有兩個版本的可執行文件時,會發生什麼?與兩個不同版本的共享庫捆綁在一起? – Tom 2011-06-10 07:45:18

-1

使用LD_LIBRARY_PATH或LD_PRELOAD幾乎是如何做到這一點。爲了解決這個問題,從MYPROG重命名你的程序MYPROG-EXE,並創建一個shell腳本,看起來像這樣叫MYPROG:

#!/bin/sh 
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH 
`dirname $0`/myprog-exe 

這樣,當有人運行MYPROG,它纔會真正運行shell腳本,然後運行myprog。

1

如果在編譯和鏈接程序時設置環境變量LD_RUN_PATH,則該搜索路徑將被烘焙到可執行文件中,動態鏈接程序將在運行時搜索它。

+0

更好地使用標誌而不是環境變量:顯式>隱式。 – Tom 2011-06-10 07:43:57