Como posso vincular estaticamente apenas algumas bibliotecas específicas ao meu binário ao vincular ao GCC?
gcc ... -static ...
tenta vincular estaticamente todas as bibliotecas vinculadas, mas não tenho a versão estática de algumas delas (por exemplo: libX11).
gcc
linker
static-libraries
Peoro
fonte
fonte
Respostas:
gcc -lsome_dynamic_lib code.c some_static_lib.a
fonte
code.c
arquivo garante que os símbolos nela serão ignorados, a menos que haja umamain()
função em um dos arquivos de objeto da biblioteca.Você também pode usar a
ld
opção-Bdynamic
Todas as bibliotecas posteriores (incluindo as do sistema vinculadas pelo gcc automaticamente) serão vinculadas dinamicamente.
fonte
você também pode usar:
-static-libgcc -static-libstdc++
flags para bibliotecas gcctenha em mente que se
libs1.so
elibs1.a
ambos existirem, o vinculador escolherálibs1.so
se é antes-Wl,-Bstatic
ou depois-Wl,-Bdynamic
. Não se esqueça de passar-L/libs1-library-location/
antes de ligar-ls1
.fonte
-static
algum lugar no comando falhe (presumo que ele tente vincular mais coisas estaticamente do que apenas as bibliotecas que desejo).-Wl,-Bstatic
e-Wl,-Bdynamic
é importante.Na página de manual de
ld
(isso não funciona com gcc), referindo-se à--static
opção:Uma solução é colocar suas dependências dinâmicas antes da
--static
opção na linha de comando.Outra possibilidade é não usar
--static
, mas em vez disso fornecer o nome do arquivo / caminho completo do arquivo de objeto estático (ou seja, não usar a opção -l) para vincular estaticamente a uma biblioteca específica. Exemplo:Como você pode ver no exemplo,
libX11
não está na lista de bibliotecas vinculadas dinamicamente, pois estava vinculado estaticamente.Cuidado: um
.so
arquivo está sempre vinculado dinamicamente, mesmo quando especificado com um nome de arquivo / caminho completo.fonte
ldd a.out
?ldd
gera as bibliotecas compartilhadas necessárias e libX11 não aparece nessa lista.O problema, pelo que entendi, é o seguinte. Você tem várias bibliotecas, algumas estáticas, algumas dinâmicas e algumas estáticas e dinâmicas. O comportamento padrão do gcc é vincular "principalmente dinâmico". Ou seja, o gcc se vincula a bibliotecas dinâmicas quando possível, mas de outra forma recorre a bibliotecas estáticas. Quando você usa a opção -static para gcc, o comportamento é apenas vincular bibliotecas estáticas e sair com um erro se nenhuma biblioteca estática puder ser encontrada, mesmo se houver uma biblioteca dinâmica apropriada.
Outra opção, que em várias ocasiões desejei que o gcc tivesse, é o que chamo de -mostly-static e é essencialmente o oposto de -dynamic (o padrão). -mostly-static , se existisse, preferiria vincular-se a bibliotecas estáticas, mas voltaria para bibliotecas dinâmicas.
Esta opção não existe, mas pode ser emulada com o seguinte algoritmo:
Construindo a linha de comando do link sem incluir -static .
Repita as opções de link dinâmico.
Acumule caminhos de biblioteca, ou seja, aquelas opções da forma -L <lib_dir> em uma variável <lib_path>
Para cada opção de link dinâmico, ou seja, aqueles do formulário -l <lib_name> , execute o comando gcc <lib_path> -print-file-name = lib <lib_name> .a e capture a saída.
Se o comando imprimir algo diferente do que você passou, será o caminho completo para a biblioteca estática. Substitua a opção de biblioteca dinâmica pelo caminho completo para a biblioteca estática.
Enxágue e repita até processar toda a linha de comando do link. Opcionalmente, o script também pode obter uma lista de nomes de bibliotecas para excluir da vinculação estática.
O seguinte script bash parece fazer o truque:
Por exemplo:
no meu sistema retorna:
ou com uma exclusão:
Eu então obtenho:
fonte
Também há
-l:libstatic1.a
(menos l dois pontos) variante da opção -l no gcc que pode ser usada para vincular a biblioteca estática (graças a https://stackoverflow.com/a/20728782 ). Está documentado? Não na documentação oficial do gcc (que não é exata para libs compartilhadas também): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlO doc binutils ld o descreve. A
-lname
opção fará a busca porlibname.so
então paralibname.a
adicionar prefixo lib e.so
(se habilitado no momento) ou.a
sufixo. Mas a-l:name
opção pesquisará apenas exatamente o nome especificado: https://sourceware.org/binutils/docs/ld/Options.htmlA variante
-l:namespec
está documentada desde a versão 2.18 de binutils (2007): https://sourceware.org/binutils/docs-2.18/ld/Options.htmlfonte
Alguns carregadores (linkers) fornecem interruptores para ligar e desligar o carregamento dinâmico. Se o GCC estiver rodando em tal sistema (Solaris - e possivelmente outros), então você pode usar a opção relevante.
Se você souber quais bibliotecas deseja vincular estaticamente, pode simplesmente especificar o arquivo de biblioteca estática na linha de link - pelo caminho completo.
fonte
para vincular a biblioteca dinâmica e estática em uma linha, você deve colocar libs estáticas após libs dinâmicas e arquivos de objeto, como este:
gcc -lssl main.o -lFooLib -o main
caso contrário, não funcionará. leva algum tempo para eu descobrir.
fonte