Мне нужно запустить php-скрипт в системе с несколько сломанной установкой PHP. Вместо того, чтобы пытаться решить проблемы, я хочу просто скомпоновать свой код с помощью собственного PHP-двоичного файла (я могу выполнить исполняемый файл). Я хочу просто иметь простой двоичный файл php, в котором есть все модули, которые мне нужно скомпилировать. Мой общий процесс:
./configure --enable-static --enable-cli --disable-all
Это дает мне двоичный файл php без расширений. Отсюда я могу добавить расширения, которые мне нужны. Например, чтобы добавить поддержку curl и json
./configure --enable-static --enable-cli --disable-all --with-curl --enable-json
Это похоже на работу в целом. Для моего скрипта необходима поддержка libxml для взаимодействия с AWS. Поэтому я добавил --enable-libxml --enable-simplexml
команду configure. Когда я копирую двоичный файл на удаленный компьютер, он получает ошибку при попытке использовать библиотеку XML, которая выглядит так:
/usr/lib/x86_64-linux-gnu/libxml2.so.2: version `LIBXML2_2.9.0' not found
Очевидно, что он динамически связывается с libxml2. Я полагаю, это означает, что, хотя расширение 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-машине.
Я нашел решение, хотя это немного грязнее, чем хотелось бы. Я оставляю libxml как общий объект и просто включаю его в свой пакет кода и используя переменную среды LD_LIBRARY_PATH, чтобы он загружал объекты моей общей библиотеки, а не те, которые были установлены в системе.
В идеале мне нужен только один двоичный файл, но это решение работает. Он также имеет небольшое преимущество в использовании системных библиотек, если они подходят (т.е. в моем пакете кода не обязательно должны быть включены все общие библиотеки). Но мне все равно было бы интересно узнать, есть ли способ скомпилировать полностью статический php-файл.
Мне было предложено давным-давно попробовать http://statifier.sf.net/ или http://magicErmine.com
Они делают статический двоичный файл из любого исполняемого файла.
Я думаю, именно так люди в magento сделали это php 5.2 двоичным.