g ++ ligando dependência de ordem ao ligar o código c ao código c ++

Antes de hoje, sempre acreditei que a ordem em que os objects e bibliotecas eram passados ​​para o g ++ durante o estágio de vinculação não era importante. Então, hoje, eu tentei link do código c ++ para o código c. Enfiei todos os headers C em um bloco externo “C”, mas o vinculador ainda tinha dificuldades em encontrar símbolos que eu sabia que estavam nos arquivos de object C.

Perplexo, criei um exemplo relativamente simples para isolar o erro de vinculação, mas para minha surpresa, o exemplo mais simples vinculado sem problemas.

Depois de uma pequena tentativa e erro, descobri que, ao emular o padrão de vinculação usado no exemplo simples, eu poderia obter o código principal para vincular o OK. O padrão era o código-object primeiro, os arquivos do object, por exemplo, em segundo lugar:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

Alguém pode lançar alguma luz sobre por que isso pode ser assim? Eu nunca vi esse problema ao ligar código c ++ comum.

A ordem em que você especifica arquivos e bibliotecas de objects é MUITO importante no GCC – se você não foi mordido por isso antes de levar uma vida encantada. O vinculador procura símbolos na ordem em que aparecem, portanto, se você tiver um arquivo de origem que contenha uma chamada para uma function de biblioteca, será necessário colocá-lo antes da biblioteca ou o vinculador não saberá que precisa resolvê-lo. O uso complexo de bibliotecas pode significar que você precisa especificar a biblioteca mais de uma vez, o que é uma dor real para acertar.

A passagem da ordem da biblioteca para gcc / g ++ realmente importa. Se A depende de B , A deve ser listado primeiro. A razão é que ele otimiza os símbolos que não são referenciados, então se ele vê a biblioteca B primeiro, e ninguém a referenciou naquele ponto, então ela não irá vincular nada a ela.

Uma biblioteca estática é uma coleção de arquivos de objects agrupados em um arquivo. Ao vincular-se a ele, o vinculador escolhe apenas os objects necessários para resolver quaisquer símbolos atualmente indefinidos. Como os objects são vinculados em ordem dada na linha de comando, os objects da biblioteca só serão incluídos se a biblioteca vier depois de todos os objects que dependem dela.

Portanto, a ordem dos links é muito importante; Se você for usar bibliotecas estáticas, precisará ter cuidado para acompanhar as dependencies e não introduzir dependencies cíclicas entre as bibliotecas.

Você pode usar –start-group archives –end-group e escrever as 2 bibliotecas dependentes em vez de arquivos

gcc main.o.o -L. -Wl, – start-group -lobj_A -lobj_b -Wl, – grupo final