2014-06-11 145 views
11

我需要在系統上運行一個PHP腳本,並且PHP安裝有些破碎。與其試圖解決我想只用自己的PHP二進制文件(我可以執行可執行文件)打包代碼的問題。我只想有一個具有我需要編譯的所有模塊簡單的PHP程序我的一般過程是:將PHP編譯爲靜態二進制文件

./configure --enable-static --enable-cli --disable-all 

這給了我一個PHP程序沒有擴展名。從這裏我可以添加我需要的擴展。例如添加捲曲和json支持

./configure --enable-static --enable-cli --disable-all --with-curl --enable-json 

這似乎一般工作。我的腳本需要libxml支持來與AWS進行交互。所以我將--enable-libxml --enable-simplexml添加到configure命令中。

/usr/lib/x86_64-linux-gnu/libxml2.so.2: version `LIBXML2_2.9.0' not found 

顯然,這是動態鏈接到的libxml2:當我的二進制文件複製到遠程機器它試圖用看起來像XML庫時收到錯誤。我認爲這意味着當PHP擴展被靜態編譯到PHP中時,PHP擴展使用的庫不是。運行LDD證實了這一點:

$ ldd sapi/cli/php 
linux-vdso.so.1 => (0x00007fff05cf3000) 
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f3c69f82000) 
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f3c69d68000) 
libcurl.so.4 => /lib64/libcurl.so.4 (0x00007f3c69afc000) 
librt.so.1 => /lib64/librt.so.1 (0x00007f3c698f4000) 
libm.so.6 => /lib64/libm.so.6 (0x00007f3c695ed000) 
libdl.so.2 => /lib64/libdl.so.2 (0x00007f3c693e8000) 
libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f3c691cf000) 
libxml2.so.2 => /lib64/libxml2.so.2 (0x00007f3c68e66000) 
libz.so.1 => /lib64/libz.so.1 (0x00007f3c68c4f000) 
libc.so.6 => /lib64/libc.so.6 (0x00007f3c68890000) 
libfreebl3.so => /lib64/libfreebl3.so (0x00007f3c6860f000) 
libidn.so.11 => /lib64/libidn.so.11 (0x00007f3c683db000) 
libssh2.so.1 => /lib64/libssh2.so.1 (0x00007f3c681b1000) 
libssl3.so => /lib64/libssl3.so (0x00007f3c67f72000) 
libsmime3.so => /lib64/libsmime3.so (0x00007f3c67d44000) 
libnss3.so => /lib64/libnss3.so (0x00007f3c679fc000) 
libnssutil3.so => /lib64/libnssutil3.so (0x00007f3c677d0000) 
libplds4.so => /lib64/libplds4.so (0x00007f3c675cb000) 
libplc4.so => /lib64/libplc4.so (0x00007f3c673c6000) 
libnspr4.so => /lib64/libnspr4.so (0x00007f3c67188000) 
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3c66f6a000) 
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f3c66d20000) 
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f3c66a40000) 
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f3c6680a000) 
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f3c66606000) 
liblber-2.4.so.2 => /lib64/liblber-2.4.so.2 (0x00007f3c663f7000) 
libldap-2.4.so.2 => /lib64/libldap-2.4.so.2 (0x00007f3c661a4000) 
/lib64/ld-linux-x86-64.so.2 (0x00007f3c6a1d7000) 
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f3c65f7f000) 
libssl.so.10 => /lib64/libssl.so.10 (0x00007f3c65d12000) 
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f3c6592b000) 
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f3c6571c000) 
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f3c65518000) 
libsasl2.so.3 => /lib64/libsasl2.so.3 (0x00007f3c652fa000) 
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f3c650d6000) 
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f3c64e6f000) 

正如你可以看到有一些動態鏈接到我的PHP二進制許多圖書館。我猜測它通常工作,因爲我的目標系統有很多這些相同的庫,但不是libxml庫。

所以我的問題是,如何製作一個完全靜態的二進制文件而不依賴於共享庫。我意識到這會使我的可執行文件更大,但這也意味着我可以將我的php可執行文件與代碼打包在一起,它可以在任何64位Linux機器上運行。

+2

修復php安裝是一個百萬倍更好的主意。 –

+0

共享系統,無法訪問。 –

+2

但它們允許二進制安裝? –

回答

3

我發現了一個解決方案,雖然它比我想要的有點混亂。我將libxml作爲共享對象離開,並將其包含在我的代碼包中,並使用LD_LIBRARY_PATH環境變量,以便加載共享庫對象而不是系統上安裝的對象。

理想情況下,我想只是一個二進制文件,但此解決方案的工作原理。如果適用的話,它也具有使用系統庫的輕微優勢(即我的代碼包不必包含所有的共享庫)。但是我仍然有興趣知道是否有一種方法可以編譯一個完全靜態的php二進制文件。

+0

嗨埃裏克,你找到了更好的方法來做到這一點?我有一個完整的基於web的醫院系統,這個系統是用php,jquery,HTML,MySQL,JavaScript和HTML開發的,醫院要求我幫助他們在一個可執行文件中編譯它。它運行在基於RPM Linux的服務器上,並且不同地理區域的醫院的其他分支也連接到它。 –

+1

不是一個單一的二進制。我結束了使用LD_LIBRARY_PATH一段時間的描述。後來該項目遷移到Docker讓我能夠更好地控制PHP的版本,而不管環境本身支持什麼。 –