Combinando bibliotecas estáticas
-
21-08-2019 - |
Pergunta
Suponha que eu tenho três C bibliotecas estáticas dizer libColor.a que depende * libRGB. * A que por sua vez depende de libPixel.a . A biblioteca libColor.a é dito que depender de biblioteca libRGB.a uma vez que existem algumas referências em libColor.a para alguns dos símbolos definidos em libRGB.a . Como faço para combinar todas as bibliotecas acima para um novo libNewColor.a , que é independente?
meios independentes a nova biblioteca deve ter todos os símbolos definidos. Assim, enquanto que liga Eu só preciso dar -lNewColor . O tamanho da nova biblioteca deve ser mínima ou seja, não deve conter quaisquer símbolos em libRGB.a que não é usado por libColor.a etc. Eu tentei a minha sorte usando várias opções em ar comando (usado para criar e atualização de bibliotecas estáticas / archives).
Solução
1 / extrair todos os arquivos objeto de cada biblioteca (usando ar
) e tentar compilar o código sem as bibliotecas ou qualquer um dos arquivos objeto. Você provavelmente vai receber um balde de carga absoluta de símbolos indefinidos. Se você não obter símbolos indefinidos, vá para a etapa 5.
2 / Grab o primeiro e descobrir qual satisfaz arquivo objeto que símbolo (usando nm
).
3 / Anote esse arquivo objeto, em seguida, compilar o código, incluindo o novo arquivo objeto. Você vai ter uma nova lista de símbolos indefinidos ou, se não houver nenhum, ir para etapa 5.
4 / Vá para o passo 2.
5 / combinar todos os arquivos objeto em sua lista (se houver) em uma única biblioteca (novamente com ar
).
bang! Aí está. Tente ligar seu código sem nenhum dos objetos, mas com a nova biblioteca.
Essa coisa toda poderia ser relativamente fácil automatizado com um script shell.
Outras dicas
Um recurso pouco usado do arquivador GNU é o script do arquivo, é uma simples, mas poderosa interface, e pode fazer exatamente o que você quer, por exemplo, se o seguinte script é chamado script.ar:
CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
SAVE
END
Em seguida, você poderia invocar ar a seguinte:
ar -M < script.ar
e você terá libNewColor.a que contém todos os arquivos .o de libColor.a libRGB.a e libPixel.a.
Além disso, você também pode adicionar arquivos .o regulares, bem como com o comando ADDMOD:
CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
ADDMOD someRandomCompiledFile.o
SAVE
END
Além disso, é super fácil de gerar esses scripts em Makefiles, então eu normalmente criar uma regra makefile bastante genérica, para a criação de arquivos que realmente gera o script e invoca AR sobre o script. Algo parecido com isto:
$(OUTARC): $(OBJECTS)
$(SILENT)echo "CREATE $@" > $(ODIR)/$(ARSCRIPT)
$(SILENT)for a in $(ARCHIVES); do (echo "ADDLIB $$a" >> $(ODIR)/$(ARSCRIPT)); done
$(SILENT)echo "ADDMOD $(OBJECTS)" >> $(ODIR)/$(ARSCRIPT)
$(SILENT)echo "SAVE" >> $(ODIR)/$(ARSCRIPT)
$(SILENT)echo "END" >> $(ODIR)/$(ARSCRIPT)
$(SILENT)$(AR) -M < $(ODIR)/$(ARSCRIPT)
Embora agora que eu olhar para ele eu acho que não funciona se $ (objetos) está vazio (ou seja, se você só quer combinar arquivos sem adicionar arquivos objeto extras), mas vou deixar isso como um exercício para o leitor para corrigir esse problema, se necessário ...: D
Aqui estão os documentos para esse recurso:
https://sourceware.org/binutils/docs/binutils/ar-scripts .html # AR-scripts
A biblioteca estática não é muito mais do que um arquivo de alguns arquivos de objetos (.o). O que você pode fazer é extrair todos os objetos nas duas bibliotecas (usando "ar x") e, em seguida, usar o "ar" para ligá-los juntos em uma nova biblioteca.