Se nós (no momento) ignorarmos a gcc
ou a parte de vinculação da pergunta e, em vez disso, modificarmos um binário com patchelf
em um sistema linux
$ ldd hello
linux-vdso.so.1 => (0x00007ffd35584000)
libhello.so.1 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f02e4f6f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f02e533c000)
$ patchelf --remove-needed libhello.so.1 hello
$ patchelf --add-needed ./libhello.so.1 hello
$ ldd hello
linux-vdso.so.1 => (0x00007ffdb74fc000)
./libhello.so.1 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f2ad5c28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2ad5ff5000)
Agora temos um binário com uma biblioteca de caminhos relativos, que se houver diretórios adequados com libhello.so.1
arquivos presentes neles
$ cd english/
$ ../hello
hello, world
$ cd ../lojban/
$ ../hello
coi rodo
descobrimos que o caminho é relativo ao diretório de trabalho do processo , que abre todos os tipos de problemas, especialmente segurança problemas . Pode haver algum uso produtivo para isso, testando diferentes versões de uma biblioteca, talvez. Provavelmente seria mais simples compilar dois binários diferentes ou patchelf
na biblioteca necessária sem a complicação de um diretório de trabalho relativo.
etapas de compilação
libhello
tem apenas uma chamada helloworld
$ cat libhello.c
#include <stdio.h>
void helloworld(void)
{
printf("coi rodo\n");
}
e foi compilado via
CFLAGS="-fPIC" make libhello.o
gcc -shared -fPIC -Wl,-soname,libhello.so.1 -o libhello.so.1.0.0 libhello.o -lc
ln -s libhello.so.1.0.0 libhello.so.1
ln -s libhello.so.1.0.0 libhello.so
e o hello
que faz a chamada helloworld
foi compilada via
$ cat hello.c
int main(void)
{
helloworld();
return 0;
}
$ CFLAGS="-lhello -L'pwd'/english" make hello
sem patchelf
Em retrospectiva, modifique o comando gcc
para usar um caminho de diretório relativo:
$ gcc -shared -fPIC -Wl,-soname,./libhello.so.1 -o libhello.so.1.0.0 libhello.o -lc
$ cd ..
$ rm hello
$ CFLAGS="-lhello -L'pwd'/lojban" make hello
$ ldd hello | grep hello
./libhello.so.1 => not found
$ english
$ ../hello
hello, world
Provavelmente é mais sensato compilar a biblioteca de uma maneira normal e depois mexer em qualquer binários, conforme necessário, usando patchelf
.