Você precisa da versão estática da biblioteca para vinculá-la.
Uma biblioteca compartilhada é realmente um executável em um formato especial com pontos de entrada especificados (e alguns problemas de endereçamento incluídos). Ele não possui todas as informações necessárias para vincular estaticamente.
Você não pode vincular estaticamente uma biblioteca compartilhada (ou vincular dinamicamente uma biblioteca estática).
A bandeira -static forçará o vinculador a usar bibliotecas estáticas (.a) em vez de compartilhadas (.so). Como as bibliotecas estáticas nem sempre são instaladas por padrão, você pode ter que instalar a biblioteca estática por conta própria.
Outra abordagem possível é usar o statifier ou o Ermine . Ambas as ferramentas tomam como entrada um executável vinculado dinamicamente e como saída criam um executável independente com todas as bibliotecas compartilhadas incorporadas.
Não existe uma maneira de dizer ao gcc diretamente o que vincular estaticamente, e não ignorá-lo e conversar com o vinculador?
Elazar Leibovich
1
@ElazarLeibovich, você não pode obter uma combinação de estática e dinâmica dessa maneira.
Haozhun 20/05
@EugeneBujak: A ressalva não se aplica ao meu sistema. Exemplo: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L.libB usa libA , está vinculado e lddnão mostra uma referência a libA . O executável funciona bem. Testado com g ++ 4.7.3.
radix
Uma dependência indireta (aninhada), estática, de uma dependência direta, dinâmica, não se torna dinamicamente vinculada.
Vinny19:
Considere o seguinte: binA depende da libB.so, que depende da libC.a Como outros já declararam, .so são eles mesmos executáveis; portanto, quando um objeto compartilhado é vinculado, qualquer dependente de uma biblioteca estática é processado pelo vinculador da mesma forma como se um executável estava sendo vinculado: os únicos símbolos extraídos da lib estática .a são aqueles referenciados (e não resolvidos) pelo .so. Isso significa que, se binA referenciar um símbolo no libC.a, não mencionado em qualquer lugar no libB.so, mesmo se binA vincular ao libB.so, esse símbolo será indefinido (a menos que -Wl, - archive inteiro seja usado ao vincular libB.so).
Vinny19:
18
Se você possui o arquivo .a da sua biblioteca compartilhada (.so), basta incluí-lo com o caminho completo, como se fosse um arquivo de objeto, como este:
Isso gera main.o apenas compilando:
gcc -c main.c
Isso vincula esse arquivo de objeto à biblioteca estática correspondente e cria o executável (chamado "main"):
Sim, eu sei que essa é uma pergunta de 8 anos, mas me disseram que era possível vincular estaticamente a uma biblioteca de objetos compartilhados e esse foi literalmente o principal sucesso quando procurei mais informações sobre ela.
Para realmente demonstrar que vincular estaticamente uma biblioteca de objetos compartilhados não é possível com o ld( gccvinculador de), em vez de apenas um monte de pessoas insistindo que isso não é possível, use o seguinte gcccomando:
(Claro que você vai ter que compilar objectname.oa partir de sourcename.c, e você provavelmente deve fazer a sua própria biblioteca de objeto compartilhado também. Se você fizer isso, o uso-Wl,--library-path,. para que ld pode encontrar sua biblioteca no diretório local.)
O erro real que você recebe é:
/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status
Execute a passagem binária como argumento, o nome do binário que você deseja tornar portátil, por exemplo: nmap
./cde_2011-08-15_64bit nmap
O programa lerá todas as bibliotecas vinculadas ao nmap e suas dependências e as salvará em uma pasta chamada cde-package / (no mesmo diretório que você).
Finalmente, você pode compactar a pasta e implantar o binário portátil em qualquer sistema.
Lembre-se, para iniciar o programa portátil, você precisa executar o binário localizado em cde-package / nmap.cde
Respostas:
Referir-se:
http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/
http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html
Você precisa da versão estática da biblioteca para vinculá-la.
Uma biblioteca compartilhada é realmente um executável em um formato especial com pontos de entrada especificados (e alguns problemas de endereçamento incluídos). Ele não possui todas as informações necessárias para vincular estaticamente.
Você não pode vincular estaticamente uma biblioteca compartilhada (ou vincular dinamicamente uma biblioteca estática).
A bandeira
-static
forçará o vinculador a usar bibliotecas estáticas (.a) em vez de compartilhadas (.so). Como as bibliotecas estáticas nem sempre são instaladas por padrão, você pode ter que instalar a biblioteca estática por conta própria.Outra abordagem possível é usar o statifier ou o Ermine . Ambas as ferramentas tomam como entrada um executável vinculado dinamicamente e como saída criam um executável independente com todas as bibliotecas compartilhadas incorporadas.
fonte
Se você deseja vincular, digamos, libapplejuice estaticamente, mas não, digamos, liborangejuice , é possível vincular assim:
Há uma ressalva - se
liborangejuice
usarlibapplejuice
, entãolibapplejuice
será dinamicamente vinculado.Você precisará vincular
liborangejuice
estaticamente ao lado delibapplejuice
para obterlibapplejuice
estática.E não se esqueça de manter o
-Wl,-Bdynamic
resto, você acabará vinculando tudo que estático, inclusivelibc
(o que não é uma coisa boa a se fazer).fonte
gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L.
libB usa libA , está vinculado eldd
não mostra uma referência a libA . O executável funciona bem. Testado com g ++ 4.7.3.Se você possui o arquivo .a da sua biblioteca compartilhada (.so), basta incluí-lo com o caminho completo, como se fosse um arquivo de objeto, como este:
Isso gera main.o apenas compilando:
Isso vincula esse arquivo de objeto à biblioteca estática correspondente e cria o executável (chamado "main"):
Ou em um único comando:
Também pode ser um caminho absoluto ou relativo:
fonte
Sim, eu sei que essa é uma pergunta de 8 anos, mas me disseram que era possível vincular estaticamente a uma biblioteca de objetos compartilhados e esse foi literalmente o principal sucesso quando procurei mais informações sobre ela.
Para realmente demonstrar que vincular estaticamente uma biblioteca de objetos compartilhados não é possível com o
ld
(gcc
vinculador de), em vez de apenas um monte de pessoas insistindo que isso não é possível, use o seguintegcc
comando:(Claro que você vai ter que compilar
objectname.o
a partir desourcename.c
, e você provavelmente deve fazer a sua própria biblioteca de objeto compartilhado também. Se você fizer isso, o uso-Wl,--library-path,.
para que ld pode encontrar sua biblioteca no diretório local.)O erro real que você recebe é:
Espero que ajude.
fonte
Um pouco tarde, mas ... Encontrei um link que salvei alguns anos atrás e achei que poderia ser útil para vocês:
CDE: Crie automaticamente aplicativos portáteis do Linux
http://www.pgbovine.net/cde.html
Execute a passagem binária como argumento, o nome do binário que você deseja tornar portátil, por exemplo: nmap
./cde_2011-08-15_64bit nmap
O programa lerá todas as bibliotecas vinculadas ao nmap e suas dependências e as salvará em uma pasta chamada cde-package / (no mesmo diretório que você).
Lembre-se, para iniciar o programa portátil, você precisa executar o binário localizado em cde-package / nmap.cde
Cumprimentos
fonte
No gcc, isso não é suportado. De fato, isso não é suportado em nenhum compilador / vinculador existente que eu conheça.
fonte