Compilação com make: link para a biblioteca

0

Estou fazendo uma compilação de PHP para um aplicativo com make. O problema é quando eu faço um ldd php eu tenho algo assim:

libk5crypto.so.3 = > /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f5b4e661000)

Mas libk5crypto.so.3 é um symlic que aponta para libk5crypto.so.3.1

Gostaria que meu php apontasse diretamente para libk5crypto.so.3.1.

É possível?

EDITAR: Eu tenho um aplicativo da web com um servidor php que eu compilar. Eu não quero instalá-lo em / etc, eu só quero que ele esteja dentro do meu aplicativo.

Dentro do meu aplicativo eu tenho uma pasta chamada server onde eu armazeno php, fop, mapserver etc ...

Dentro da minha pasta php, eu tenho uma pasta lib e dentro coloco todas as dependências (ldd bin / php)

Quando eu instalo meu aplicativo, eu modifico o arquivo /etc/ld.so.conf para adicionar o diretório lib do meu servidor php, então eu faço um ldconfig.

Às vezes, as bibliotecas já existem em / usr / lib / x86_64-linux-gnu e o PHP pega essas libs em vez da pasta em sua pasta. Quase não é um problema, mas às vezes eu tenho uma lib dentro de / usr / lib ... que tem a mesma versão principal mas tem uma versão secundária menor. O PHP tenta obtê-lo de / usr / lib e me lança um erro porque o php foi copiado com as dependências mais recentes.

É por esse motivo que quero apontar diretamente para libk5crypto.so.3.1.

Quando eu atualizo meu aplicativo, eu apago meu php e coloco um novo com todas as novas libs.

Outra coisa, eu tento dizer ao PHP para procurar as libs em um determinado diretório, mas meu problema eu não sei onde será em tempo de compilação.

EDIT para JigglyNaga: Eu compilo PHP, então eu compilo imap e outras extensões. O problema é com o php e a extensão. Então a compilação é mais curta para o imap, então eu te dou tudo.

root@ubuntu16:~/compilPHP/php-7.2.2/ext/imap# make
/bin/bash /root/compilPHP/php-7.2.2/ext/imap/libtool --mode=compile cc  -I. -I/root/compilPHP/php-7.2.2/ext/imap -DPHP_ATOM_INC -I/root/compilPHP/php-7.2.2/ext/imap/include -I/root/compilPHP/php-7.2.2/ext/imap/main -I/root/compilPHP/php-7.2.2/ext/imap -I/php/include/php -I/php/include/php/main -I/php/include/php/TSRM -I/php/include/php/Zend -I/php/include/php/ext -I/php/include/php/ext/date/lib -I/usr/include/c-client  -DHAVE_CONFIG_H  -g -O2   -c /root/compilPHP/php-7.2.2/ext/imap/php_imap.c -o php_imap.lo
mkdir .libs
cc -I. -I/root/compilPHP/php-7.2.2/ext/imap -DPHP_ATOM_INC -I/root/compilPHP/php-7.2.2/ext/imap/include -I/root/compilPHP/php-7.2.2/ext/imap/main -I/root/compilPHP/php-7.2.2/ext/imap -I/php/include/php -I/php/include/php/main -I/php/include/php/TSRM -I/php/include/php/Zend -I/php/include/php/ext -I/php/include/php/ext/date/lib -I/usr/include/c-client -DHAVE_CONFIG_H -g -O2 -c /root/compilPHP/php-7.2.2/ext/imap/php_imap.c  -fPIC -DPIC -o .libs/php_imap.o
/bin/bash /root/compilPHP/php-7.2.2/ext/imap/libtool --mode=link cc -DPHP_ATOM_INC -I/root/compilPHP/php-7.2.2/ext/imap/include -I/root/compilPHP/php-7.2.2/ext/imap/main -I/root/compilPHP/php-7.2.2/ext/imap -I/php/include/php -I/php/include/php/main -I/php/include/php/TSRM -I/php/include/php/Zend -I/php/include/php/ext -I/php/include/php/ext/date/lib -I/usr/include/c-client  -DHAVE_CONFIG_H  -g -O2   -o imap.la -export-dynamic -avoid-version -prefer-pic -module -rpath /root/compilPHP/php-7.2.2/ext/imap/modules  php_imap.lo -Wl,-rpath,/usr/lib/x86_64-linux-gnu/mit-krb5 -L/usr/lib/x86_64-linux-gnu/mit-krb5 -lc-client -lcrypt -lpam -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto
cc -shared  .libs/php_imap.o  -L/usr/lib/x86_64-linux-gnu/mit-krb5 -lc-client -lcrypt -lpam -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto  -Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu/mit-krb5 -Wl,-soname -Wl,imap.so -o .libs/imap.so
creating imap.la
(cd .libs && rm -f imap.la && ln -s ../imap.la imap.la)
/bin/bash /root/compilPHP/php-7.2.2/ext/imap/libtool --mode=install cp ./imap.la /root/compilPHP/php-7.2.2/ext/imap/modules
cp ./.libs/imap.so /root/compilPHP/php-7.2.2/ext/imap/modules/imap.so
cp ./.libs/imap.lai /root/compilPHP/php-7.2.2/ext/imap/modules/imap.la
PATH="$PATH:/sbin" ldconfig -n /root/compilPHP/php-7.2.2/ext/imap/modules

EDIÇÃO FINAL: Funcionou, eu mudo o rpath antes de fazer a marca. export LDFLAGS = '- Wl, -rpath, \ $$ {ORIGEM} /../ lib' Muito obrigado por todas as suas respostas.

    
por Sébastien Legrand 12.02.2018 / 15:15

2 respostas

1

Adicionando isso como outra resposta, porque o outro ainda pode ficar por conta própria, mas o seu problema (depois de esclarecido) é diferente. Se isso é sobre bibliotecas que são enviadas com seu aplicativo e também pelo sistema, a situação não é comparável. Você está quase no que precisa fazer para consertar, mas não completamente: -)

Existem várias soluções para o seu problema: LD_LIBRARY_PATH , rpath , envio de bibliotecas alteradas e compilação várias vezes. Cada um tem suas vantagens e problemas, então deixe-me explicar:

  • LD_LIBRARY_PATH

    Se você percorrer esse caminho, defina uma variável de ambiente antes de executar o programa. Ele provavelmente requer que você use um script de wrapper em torno do seu binário (ou seja, em vez de executar diretamente o /path/to/my/php , você executa um script de shell que define LD_LIBRARY_PATH e executa /path/to/my/php ).

    A desvantagem desse método é que ele é um pouco frágil:

    • LD_LIBRARY_PATH é prefixado no caminho de pesquisa da biblioteca, mas não o substitui. Isso significa que, se as bibliotecas em questão estiverem instaladas em todo o sistema, mas por algum motivo as que você enviou não puderem ser carregadas, o vinculador dinâmico recorrerá às fornecidas pelo sistema.
    • O requisito para chamar um script de shell significa que você tem uma chamada fork / exec extra, o que pode fazer com que as coisas corram mal. Isso pode ser atenuado de alguma forma usando o comando exec em seu script de shell (para que o script seja substituído pelo binário php e para que seu programa php seja um filho adequado do pai), mas ainda é confuso

    Por outro lado, permite alguma flexibilidade com o local onde você armazena suas bibliotecas (ou seja, se o sistema fornecido for bom o suficiente em alguns casos, tudo bem se você removê-lo do diretório LD_LIBRARY_PATH )

  • rpath

    Aqui, a idéia é que você diga ao compilador (por meio de gcc -Wl,-rpath,'/path/to/library' ) exatamente onde procurar pela biblioteca. Isso é embutido no programa em tempo de compilação, e o vinculador dinâmico ignorará absolutamente as versões da biblioteca que estão fora do seu fornecido rpath , incluindo as versões fornecidas pelo sistema. Isso evita a bagunça do LD_LIBRARY_PATH acima, mas a desvantagem é que isso torna as coisas menos flexíveis; se você precisar mover as coisas no sistema de arquivos, você precisará recompilar tudo.

    Isso também significa que, se seus usuários quiserem ver as coisas instaladas de uma maneira diferente, eles não terão sorte. Eles podem não gostar disso.

Ambos os métodos estão documentados na página ld.so man.

  • Envio de bibliotecas alteradas

    Aqui, a ideia é que, em vez de tentar vincular a libk5crypto.so.3 , você vincule a libmycorp-k5crypto.so.3 . Não haverá chance alguma do vinculador dinâmico pegar o libk5crypto.so.3 fornecido pelo sistema nesse caso. A vantagem aqui é que é bastante fácil e elegante, uma vez instalado; A desvantagem é que as pessoas podem começar a se perguntar se você alterou libk5crypto (e solicitará patches), e também precisará mergulhar fundo no sistema libk5crypto.so build para fazer com que ele realmente emita uma biblioteca libmycorp-k5crypto.so . Também pode parecer ruim a longo prazo, então tenha cuidado antes de seguir esse caminho.

  • Compilando várias vezes

    Em vez de distribuir as bibliotecas que também são fornecidas em todo o sistema, você pode apenas compilar seu aplicativo em todas as distribuições suportadas e enviar um pacote para toda e qualquer distribuição, em vez de distribuir suas bibliotecas. Coisas como packagecloud.io tornam isso mais fácil de fazer. Como existe apenas uma biblioteca com um nome no sistema, há apenas uma biblioteca para escolher e nenhuma chance de escolher a biblioteca errada. A desvantagem é que você tem um leque maior de coisas para testar, então você tem mais trabalho no momento do lançamento (e é melhor ter uma boa suíte de testes).

    A vantagem é que esse método garante o envio de menos do que você faria (assim, você tem menos suporte) e pode informar aos usuários que estão em uma distribuição que possui uma versão mais antiga de libk5crypto.so que você não possui mais suporte, que eles devem atualizar isso primeiro.

por 13.02.2018 / 17:54
2

Não tenho certeza se é possível, mas não será; é uma péssima ideia.

A biblioteca SONAME s (a coisa libfoo.so.X) é definida na biblioteca. Você pode pensar que o caminho completo está no seu binário php, mas não é; apenas o SONAME é. É por isso que a saída ldd mostra libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 na saída: o nome libk5crypto.so.3 , neste sistema , resolve o arquivo sob esse diretório /usr/lib/x86_64-linux-gnu .

Não é garantido que o arquivo libk5crypto.so.3 seja sempre encontrado nesse local. A parte x86_64-linux-gnu no caminho é uma oferta inoperante que você está executando Debian ou um de seus derivados; outras distribuições que suportam apenas biarch em vez de multiarch completo, como o Red Hat, usam /usr/lib64 . Cabe ao vinculador dinâmico em tempo de execução, que você pode depurar por meio de ldd , para descobrir onde seu libk5crypto.so.3 é encontrado, usando sua configuração (normalmente /etc/ld.so.conf ).

O SONAME tem uma semântica muito particular. Se você estiver interessado em todos os detalhes técnicos, eu posso recomendar de coração o excelente documento de Ulrich Drepper sobre o assunto; mas ausente disso, você deve entender que a parte .so.3 do nome do arquivo codifica a parte compatível da API. A idéia é que quando você atualiza libk5crypto por algum motivo, o sistema instala a nova biblioteca como, digamos, libk5crypto.so.3.2 , move o symlink e finalmente remove a biblioteca antiga. Isso significa que, enquanto a biblioteca permanecer compatível com ABI , quaisquer programas compilados contra ela não precisam ser recompilados apenas porque você atualiza a biblioteca.

Se você codificar o nome completo da biblioteca no binário, no entanto, essa vantagem desaparece completamente e, como resultado, você terá que recompilar cada atualização da biblioteca. Você quase certamente não quer isso.

Dito tudo isso, essa pergunta parece ser um problema XY . O que exatamente, exatamente, você está tentando alcançar?

    
por 12.02.2018 / 15:34