Há três coisas que você precisa resolver ao compilar / vincular em um pacote não padrão:
- cabeçalhos (geralmente
CFLAGS
) - caminho da biblioteca em tempo de compilação (geralmente
LDFLAGS
) - caminho da biblioteca de tempo de execução ( rpath via
LDFLAGS
,LD_RUN_PATH
,LD_LIBRARY_PATH
ould.so.conf
)
Você não disse o que é prog
, então não posso saber o quão bem comportada é sua configuração (ou se usa o autoconf?), eu já vi muitos que realizam as duas primeiras etapas de maneira confiável.
Durante o estágio de link, a ordem do caminho da biblioteca é relevante, presumindo que você esteja usando o conjunto de ferramentas GNU (gcc & binutils), provavelmente você verá o que está acontecendo configurando CFLAGS
antes de configure
(ou possível no Makefile
diretamente):
export CFLAGS="-Wl,-t"
Isso passa a opção -t
trace para o vinculador. Você pode precisar adicionar V=1
ou VERBOSE=1
ao comando make se somente as linhas "CC" e "LD" forem emitidas durante a criação.
Em tempo de execução, você pode ver o que ld.so
tenta definir com cuidado LD_DEBUG
, por exemplo
LD_DEBUG=libs ./myprog
(ou tente valores de files
ou symbols
para mais detalhes)
Para especificar todos os três parâmetros corretamente no tempo de compilação, você deve ser capaz de fazer:
-
export CFLAGS="-I/usr/local/ssl-1.0.2/include"
-
export LDFLAGS="-L/usr/local/ssl-1.0.2/lib -R/usr/local/ssl-1.0.2/lib"
reconfigure / recompile.
Você está usando --openssldir
em vez do mais convencional --prefix
(eu recomendo o último e também usando apenas make install_sw
se você não precisa das 1000 páginas man & symlinks que uma instalação padrão oferece ). Isso pode ser parte do problema. Por algum motivo, as bibliotecas .so que você mostra são conhecidas por ld.so
e não têm um sufixo de versão (por exemplo, .so.1.0.2
), um " make install
" adequado deve ter configurado isso para você (via link-shared
target no principal Makefile
).
A opção -R
instrui o vinculador a incorporar um RPATH na saída executável da biblioteca OpenSSL específica, para que não precise depender do padrão que o vinculador de tempo de execução ( ld.so
) normalmente forneceria. Você pode modificar os binários existentes com chrpath
.
Isso é mais ou menos equivalente a exportar LD_LIBRARY_PATH=/usr/local/ssl-1.0.2/lib
. Você pode ler mais sobre o RPATH e o RUNPATH relacionado aqui: link
Como último recurso, você poderia construir o OpenSSL sem "compartilhado" ou com "noshared", isso forneceria bibliotecas estáticas que não terão esse problema (mas podem ter outros problemas, por exemplo, para uso no ELF .so , causando problemas PIC / PIE)
Com base nos detalhes atualizados, acredito que o problema é que 1.0.1 e 1.0.2beta definem o sufixo da versão .so (SONAME) como 1.0.0. No primeiro sistema com apenas 0.9.8 isso não causa problemas; no segundo com 1.0.1 e 1.0.2 ambos versionados como 1.0.0, é o "primeiro jogo ganha" baseado na ordem ld.so.{conf,d}
. Lembre-se, ld
o vinculador de tempo de compilação é um programa diferente para ld.so
do vinculador de tempo de execução e pode ter um comportamento diferente (geralmente resultando em erros de símbolo ou pior, como você viu).
$ cd /usr/local/src/openssl/openssl/1.0.2beta1
$ readelf -a libssl.so | grep SONAME
0x0000000e (SONAME) Library soname: [libssl.so.1.0.0]
$ cat verchk.c
int main(int argc, char *argv[]) {
printf("build: %s\n",OPENSSL_VERSION_TEXT);
printf("run : %s\n",SSLeay_version(SSLEAY_VERSION));
return 0;
}
$ gcc -Wall -I/usr/local/src/openssl/openssl-1.0.2-beta1/include \
-Wl,-rpath /usr/local/src/openssl/openssl-1.0.2-beta1/ \
-o verchk /usr/local/src/openssl/openssl-1.0.2-beta1/libcrypto.so verchk.c
$ ./verchk
build: OpenSSL 1.0.2-beta1 24 Feb 2014
run : OpenSSL 1.0.2-beta1 24 Feb 2014
$ grep SHLIB_M...R= Makefile
SHLIB_MAJOR=1
SHLIB_MINOR=0.0
Atualizar
O OpenSSL-1.1 fez algumas alterações no nível da API, o código acima falhará na compilação com cabeçalhos v1.1 e bibliotecas antigas ( undefined reference to 'OpenSSL_version'
).
SSLeay_version()
agora está reprovado e (dependendo de OPENSSL_API_COMPAT
) pode ser #define
-d para a função de API adequada OpenSSL_version()
.