我想通過Makefile.PL在linux主機上建立DBD :: Pg;我的要求是這樣的,我必須能夠動態鏈接到perl,但靜態鏈接到libpq.so(因爲它可能不適用於所有的盒子)。靜態鏈接DBD :: Pg(針對libpq.so)但動態地反對Perl?
有沒有簡單的方法來做到這一點?我試過改變Makefile.PL的LIBS指令中的鏈接選項,但MakeMaker忽略了我的選項。
我想通過Makefile.PL在linux主機上建立DBD :: Pg;我的要求是這樣的,我必須能夠動態鏈接到perl,但靜態鏈接到libpq.so(因爲它可能不適用於所有的盒子)。靜態鏈接DBD :: Pg(針對libpq.so)但動態地反對Perl?
有沒有簡單的方法來做到這一點?我試過改變Makefile.PL的LIBS指令中的鏈接選項,但MakeMaker忽略了我的選項。
IMO你錯誤地指定了你的要求。
您不需要靜態鏈接到libpq
,因爲它可能不適用於所有系統。
什麼,你通常應該做的,而不是爲動態鏈接到libq
,要麼在一個包裝腳本設置LD_LIBRARY_PATH
或使用rpath
鏈接,這樣libpq
可以找到。
要知道,雖然無論是靜態或動態鏈接,如果一些其它的模塊加載libpq
到同一個Perl的你會要麼得到兩個不兼容的libpq
s鏈接,進入同一個可執行文件(熱潮)或使用libpq
一個模塊除了它被編譯的那個(也是繁榮)之外。如果您使用rpath鏈接,ld.so
對鏈接範圍的瞭解可能會讓您放棄,但設置LD_LIBRARY_PATH
幾乎肯定會導致問題。
您可能想用rpath
與$ORIGIN
進行調查。
不幸的是,試圖做靜態鏈接的libpq
不可能解決你的問題。
libpq
本身很可能取決於libc
(glibc
)。如果您將其靜態鏈接,但是其他模塊動態鏈接,則意味着您將擁有libc
的兩個副本:一個在libpq
之內,另一個由Perl本身引用並動態加載。這是非常危險的情況,特別是如果某些過程使用malloc
分配內存並將指針傳回給調用者。如果你有一個由malloc從libc
的一個拷貝分配的內存,但free
由另一個拷貝拷貝,你的程序(和Perl)肯定會崩潰。
換句話說,如果你想要去的靜態,你必須去一路通 - 一切,必須100%進行靜態編譯,所以libc
只有一個副本使用你的應用程序。而事實恰恰相反 - 如果你是動態的,一切都應該是動態的,因爲只有使用libc
的一個副本。這些規則僅適用於您的庫不使用libc
(甚至不包括sprintf
)中的任何內容。
即使您在靜態編譯libpq
並且它將工作(不太可能),如果未安裝DBI
會怎麼樣?我已經看到了足夠的Linux框,其中DBI默認不存在。你是否也靜態編譯DBI?如果Perl
不存在(如果不是這種情況發生在Linux上),或者如果它很舊?
妥善解決是使用本地OS包管理器進行安裝:
sudo apt-get install libdbd-pg-perl # Ubuntu/Debian
sudo yum install perl-DBD-Pg # Redhat/Fedora
如果你沒有在主機上根的問題,也許你應該考慮使用perlbrew
- 在主目錄中安裝自己的Perl。有了這個,你應該能夠編譯你自己的libpq
副本,並將它與動態提供的Perl鏈接perlbrew
連接起來。
對靜態鏈接+1的問題很好的解釋 –
我不確定我是否按照你的回答;我怎樣才能保證我的模塊在運行時工作(就擁有正確的庫而言)? – Blaskovicz
使用'rpath'或'LD_LIBRARY_PATH'。 –
不要同時以不同的方式修改庫的搜索路徑嗎?我在說我想在框X(它有libpq)上構建模塊並在框Y(它沒有libpq)上運行它。也許我沒有追隨;我不是非常精通任何方式進行鏈接/編譯。 – Blaskovicz