Opções Estaticamente Vinculadas Em Binário
Vincule bibliotecas após arquivos de objeto especialmente bibliotecas estáticas. Em versões antigas e modernas do ambiente de link (I39m não tenho certeza do status quo para versões modestas antigas a partir de novembro de 2010), listando a biblioteca estática antes que o arquivo code. c garanta que os símbolos nele serão ignorados a menos que ocorra Ser uma função principal () em um dos arquivos de objetos da biblioteca. Ndash Jonathan Leffler 20 de abril 14 às 21:09 jb por padrão, gcc links dinamicamente. Quando você usa - lsomedynamiclib, ele é vinculado dinamicamente como esperado. Mas, quando o gcc recebe uma biblioteca estática de forma explícita, ele sempre tentará conectá-la de forma estática. Há, no entanto, alguns detalhes complicados sobre a ordem em que os símbolos se resolvem. Não tenho certeza de como isso funciona. Aprendi que, em caso de dúvida, tente reorganizar a ordem das bandeiras da biblioteca :-) ndash bchurchill 5 de agosto às 23:02 A partir da página de manual do ld (isso não funciona com gcc), referindo-se à opção - estática: Você pode Use esta opção várias vezes na linha de comando: ela afeta a biblioteca procurando por - l opções que a seguem. Uma solução é colocar suas dependências dinâmicas antes da opção - estática na linha de comando. Outra possibilidade é não usar - estático. Mas, em vez disso, fornecem o caminho completo do arquivo de objeto estático (isto é, não usando a opção - l) para estabelecer uma ligação estática de uma biblioteca específica. Exemplo: Como você pode ver no exemplo, o libX11 não está na lista de bibliotecas vinculadas dinamicamente, pois foi vinculado de forma estática. Cuidado: um arquivo. so sempre está vinculado dinamicamente, mesmo quando especificado com um caminho de nome de arquivo completo. Respondeu 11 de novembro às 15:40 O problema, como eu entendo, é 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 é ligar principalmente dinâmico. Ou seja, links gcc para bibliotecas dinâmicas sempre que possível, mas de outra forma retorna às 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 que haja uma biblioteca dinâmica apropriada. Outra opção, que muitas vezes desejei ter gcc, é o que eu chamo - quase sempre - estático e é essencialmente o oposto de - dynamic (o padrão). - a maioria - estática, se existisse, prefere ligar-se a bibliotecas estáticas, mas retornaria a 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. Iterate sobre as opções do link dinâmico. Acumule caminhos de biblioteca, ou seja, as opções do formulário - Lltlibdirgt em uma variável ltlibpathgt Para cada opção de link dinâmico, ou seja, as do formulário - lltlibnamegt. Execute o comando gcc ltlibpathgt - print-file-namelibltlibnamegt. 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 da biblioteca dinâmica pelo caminho completo da biblioteca estática. Enxágüe e repita até que você tenha processado toda a linha de comando do link. Opcionalmente, o script também pode ter uma lista de nomes de biblioteca para excluir da ligação estática. O seguinte script bash parece fazer o truque: no meu sistema retorna: ou com uma exclusão: há (na maioria dos casos, descontando o código interpretado) duas etapas em obter do código-fonte (o que você escreve) para o código executável (o que você executa ). A primeira é a compilação que transforma o código-fonte em módulos de objeto. O segundo, vinculando, é o que combina módulos de objetos juntos para formar um executável. A distinção é feita, entre outras coisas, permitindo que as bibliotecas de terceiros sejam incluídas no seu executável sem que você veja seu código-fonte (como bibliotecas para acessar o banco de dados, comunicações de rede e interfaces gráficas de usuário) ou para compilar código em diferentes idiomas ( C e código de montagem, por exemplo) e, em seguida, ligando todos juntos. Quando você vincula estáticamente um arquivo em um executável, o conteúdo desse arquivo está incluído no tempo do link. Em outras palavras, o conteúdo do arquivo está fisicamente inserido no executável que você executará. Quando você liga dinamicamente. Um ponteiro para o arquivo que está sendo vinculado (o nome do arquivo do arquivo, por exemplo) está incluído no executável e o conteúdo desse arquivo não está incluído no tempo do link. É somente quando você executa mais tarde o executável que esses arquivos vinculados dinamicamente são comprados e eles só são comprados na cópia na memória do executável, e não no disco. É basicamente um método de ligação diferida. Há um método ainda mais diferido (chamado de ligação tardia em alguns sistemas) que não trará o arquivo dinamicamente vinculado até que você tente realmente chamar uma função dentro dele. Os arquivos com ligação estática são bloqueados no executável no tempo do link para que eles nunca mudem. Um arquivo dinamicamente vinculado referenciado por um executável pode mudar apenas substituindo o arquivo no disco. Isso permite atualizações da funcionalidade sem ter que re-ligar o código do carregador re-links toda vez que você o executa. Isso é bom e ruim - por um lado, permite atualizações e correções de bugs mais fáceis, por outro lado, pode levar a que os programas deixem de funcionar se as atualizações forem incompatíveis - às vezes é responsável pelo temido inferno DLL que algumas pessoas mencionam em Que as aplicações podem ser quebradas se você substituir uma biblioteca vinculada dinamicamente com uma que não seja compatível (os desenvolvedores que fazem isso devem esperar ser caçados e punidos severamente, a propósito). Como um exemplo . Vamos ver o caso de um usuário compilando seu arquivo main. c para ligação estática e dinâmica. Você pode ver no caso estático que o programa principal e a biblioteca de tempo de execução C estão ligados entre si no momento do link (pelos desenvolvedores). Como o usuário normalmente não pode re-ligar o executável, eles estão presos com o comportamento da biblioteca. No caso dinâmico, o programa principal está vinculado à biblioteca de importação de tempo de execução C (algo que declara o que está na biblioteca dinâmica, mas na verdade não a define). Isso permite que o vinculador seja vinculado mesmo que o código atual esteja faltando. Em seguida, no tempo de execução, o carregador do sistema operacional faz uma ligação tardia do programa principal com a DLL de tempo de execução C (biblioteca de links dinâmicos ou biblioteca compartilhada ou outra nomenclatura). O proprietário do tempo de execução C pode soltar uma nova DLL a qualquer momento para fornecer atualizações ou correções de bugs. Conforme mencionado anteriormente, isso tem vantagens e desvantagens. Há um lugar especial reservado no nono círculo do inferno para aqueles que atualizam suas DLLs e quebram a compatibilidade com versões anteriores. Sim, se as interfaces desaparecerem ou forem modificadas, o link dinâmico cairá em uma pilha. É por isso que não deve ser feito. Por favor, adicione uma função2 () à sua DLL, mas não altere a função () se as pessoas estiverem usando. A melhor maneira de lidar com isso é recodificar a função () de tal forma que chama function2 (), mas não altere a assinatura da função (). Ndash paxdiablo 12 de maio 10 às 8:26 Acho que uma boa resposta a esta pergunta deve explicar o que é a ligação. Quando você compila algum código C (por exemplo), ele é traduzido para o idioma da máquina. Apenas uma seqüência de bytes que, quando executado, faz com que o processador adicione, subtraia, compare, goto, leia memória, escreva memória, esse tipo de coisa. Este material é armazenado em arquivos de objeto (.o). Agora, há muito tempo, cientistas da computação inventaram essa coisa de sub-rotina. Execute-this-chunk-of-code-and-return-here. Não demorou muito antes de perceberem que as sub-rotinas mais úteis poderiam ser armazenadas em um lugar especial e usadas por qualquer programa que as necessitasse. Agora, nos primeiros dias, os programadores teriam que perfurar no endereço de memória em que essas sub-rotinas estavam localizadas. Algo como CALL 0x5A62. Isso era tedioso e problemático se esses endereços de memória sempre precisassem ser alterados. Então, o processo foi automatizado. Você escreve um programa que chama printf (). E o compilador não conhece o endereço de memória do printf. Então, o compilador apenas escreve CALL 0x0000. E adiciona uma nota ao arquivo de objeto dizendo que deve substituir este 0x0000 pela localização da memória do printf. A ligação estática significa que o programa vinculador (o GNU é chamado ld) adiciona o código da máquina da impressora diretamente ao seu arquivo executável e muda o 0x0000 para o endereço do printf. Isso acontece quando seu executável é criado. A ligação dinâmica significa que o passo acima não acontece. O arquivo executável ainda possui uma nota que diz que deve substituir 0x000 pela localização da memória do printf. O carregador de sistemas operacionais precisa encontrar o código printf, carregá-lo na memória e corrigir o endereço CALL, cada vez que o programa é executado. É comum que os programas chamem algumas funções que serão vinculadas estáticamente (as funções de biblioteca padrão, como printf, geralmente estão vinculadas estáticamente) e outras funções que estão vinculadas dinamicamente. Os estáticos tornam-se parte do executável e os dinâmicos se juntam quando o executável é executado. Existem vantagens e desvantagens para ambos os métodos e existem diferenças entre os sistemas operacionais. Mas desde que você não perguntou, acabei com isso aqui. Respondeu 23 de novembro 08 às 0:02 Como nenhuma das postagens acima mostra como ligar estáticamente qualquer coisa e ver que você fez isso corretamente, então eu abordarei este problema: um programa C simples. Ligue dinamicamente o programa C E execute o arquivo no binário : E isso irá mostrar que está ligado dinamicamente algo ao longo das linhas de: simpleprog: ELF 64 bit LSB executável, x86-64, versão 1 (SYSV), vinculado dinamicamente (usa libs compartilhados), para GNU Linux 2.6.26, BuildIDsha10xf715572611a8b04f686809d90d1c0d75c6028f0f , Não despojado Em vez disso, deixe-nos estaticamente ligar o programa desta vez: o arquivo executado neste binário estáticamente ligado mostrará: simpleprog: ELF 64 bits LSB executável, x86-64, versão 1 (GNU Linux), estáticamente vinculado, para GNU Linux 2.6 .26, BuildIDsha10x8c0b12250801c5a7c7434647b7dc65a644d6132b, não despojado E você pode ver que está felizmente ligado estáticamente. Infelizmente, no entanto, nem todas as bibliotecas são simples de estabelecer esteticamente esta maneira e podem exigir um esforço prolongado usando libtool ou ligando o código objeto e bibliotecas C à mão. Felizmente, muitas bibliotecas C incorporadas, como a Musl, oferecem opções de ligação estática para quase todas, se não todas as suas bibliotecas. Agora, abrace o binário que você criou e você pode ver que não há bibliotecas acessadas antes do início do programa: agora, compare com a saída de strace no programa dinamicamente vinculado e você verá que as versões vinculadas estáticamente strace são muito mais curtas
Comments
Post a Comment