Eu criei o PHP como um módulo do apache (libphp56.so) e o vinculei ao libcurl do MacPorts. No entanto, o httpd falha ao iniciar (via launchd) se libphp56.so é carregado, imprimindo um erro de incompatibilidade de versão da biblioteca.
Eu executei o script de configuração do PHP com --with-curl=/opt/local
para vinculá-lo a /opt/local/lib/libcurl.4.dylib (fornecido pelo MacPorts). Essa cópia do libcurl é a versão 9.0.0, mas o dyld afirma que a versão 7.0.0 está sendo carregada, que por acaso é a versão do /usr/lib/libcurl.4.dylib. Por enquanto, estou assumindo que o último está sendo carregado.
apachectl
chama launchctl
para executar o httpd. Se executado diretamente, o httpd carrega libphp56.so e é executado sem erros.
Aqui estão algumas informações relevantes da linha de comando (espaço em branco adicionado para facilitar a leitura):
$ sudo -s # apachectl configtest httpd: Syntax error on line 174 of /private/etc/apache2/httpd.conf: Cannot load libexec/apache2/libphp56.so into server: dlopen(/Library/WebServer/libexec/apache2/libphp56.so, 10): Library not loaded: /opt/local/lib/libcurl.4.dylib Referenced from: /Library/WebServer/libexec/apache2/libphp56.so Reason: Incompatible library version: libphp56.so requires version 9.0.0 or later, but libcurl.4.dylib provides version 7.0.0 # /usr/sbin/httpd # ps -ax -O gid | grep /usr/sbin/httpd 6878 0 ?? Ss 0:00.22 /usr/sbin/httpd 6901 70 ?? S 0:00.00 /usr/sbin/httpd 6907 0 s008 S+ 0:00.00 grep --color=auto /usr/sbin/httpd # kill -TERM 6878 # otool -L /opt/local/lib/libcurl.4.dylib | grep libcurl /opt/local/lib/libcurl.4.dylib: /opt/local/lib/libcurl.4.dylib (compatibility version 9.0.0, current version 9.0.0) # otool -L /usr/lib/libcurl.4.dylib | grep libcurl /usr/lib/libcurl.4.dylib: /usr/lib/libcurl.4.dylib (compatibility version 7.0.0, current version 8.0.0) # otool -L /Library/WebServer/libexec/apache2/libphp56.so | grep libcurl /opt/local/lib/libcurl.4.dylib (compatibility version 9.0.0, current version 9.0.0) # echo "x${DYLD_LIBRARY_PATH}x" xx # grep -r 'DYLD_.*_PATH' /etc # launchctl getenv DYLD_LIBRARY_PATH
O launchd.plist para o httpd é bastante básico:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>EnvironmentVariables</key>
<dict>
<key>XPC_SERVICES_UNAVAILABLE</key>
<string>1</string>
</dict>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>Label</key>
<string>org.apache.httpd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/httpd</string>
<string>-D</string>
<string>FOREGROUND</string>
</array>
</dict>
</plist>
Definindo as variáveis de ambiente de relatório dyld DYLD_PRINT_TO_FILE
, DYLD_PRINT_ENV
and DYLD_PRINT_LIBRARIES
revela conjuntos de launchd DYLD_LIBRARY_PATH e /usr/lib/libcurl.4.dylib é carregado.
# DYLD_PRINT_TO_FILE=~/httpd.log DYLD_PRINT_ENV=1 DYLD_PRINT_LIBRARIES=1 apachectl configtest # grep -P 'curl|DYLD_' ~/httpd.log DYLD_PRINT_TO_FILE=/Users/Capra/httpd.log DYLD_PRINT_LIBRARIES=1 DYLD_PRINT_ENV=1 DYLD_PRINT_LIBRARIES=1 DYLD_PRINT_TO_FILE=/Users/Capra/httpd.log DYLD_LIBRARY_PATH=/usr/lib DYLD_PRINT_ENV=1 dyld: loaded: /usr/lib/libcurl.4.dylib # echo > ~/http.log # DYLD_PRINT_TO_FILE=~/httpd.log DYLD_PRINT_ENV=1 DYLD_PRINT_LIBRARIES=1 /usr/sbin/httpd -D FOREGROUND ^C # grep -P 'curl|DYLD_' ~/httpd.log DYLD_PRINT_TO_FILE=/Users/Capra/httpd.log DYLD_PRINT_LIBRARIES=1 DYLD_PRINT_ENV=1 dyld: loaded: /opt/local/lib/libcurl.4.dylib dyld: unloaded: /opt/local/lib/libcurl.4.dylib dyld: loaded: /opt/local/lib/libcurl.4.dylib
Note que libcurl não é a única biblioteca a sofrer este problema. Durante a solução de problemas, deixei de fora a extensão curl do PHP como parte da compilação e recebi uma mensagem semelhante em relação à libxml.
Como posso desfazer DYLD_LIBRARY_PATH
do httpd quando executado via launchd? Quais são as ramificações de segurança?
DYLD_LIBRARY_PATH
em org.apache.httpd.plist. DYLD_LIBRARY_PATH
Enquanto eu poderia ligar contra o libcurl do sistema, eu estou procurando uma maneira de executar o PHP com componentes atualizados; ligar /usr/lib/libcurl.4.dylib é apenas um último recurso. Evitar o launchd inteiramente, não incluindo as extensões / bibliotecas PHP afetadas na compilação e substituindo o sistema libcurl também são consideradas não-soluções. Eu quase consideraria ter um invólucro que se movesse.
Tags php osx apache-httpd