Palavras-chave: C, linkagem estática, undefined reference, referência indefinida
Ao linkar programas que usam bibliotecas estáticas que por usa vez usam outras bibliotecas estáticas, pode ocorrer de o linker reclamar da falta de símbolos de uma das bibliotecas, apesar de eles estarem comprovadamente definidos em uma delas. Isso pode ocorrer por causa da ordem errada em que as bibliotecas foram passadas ao linker.
Apesar de o linker se virar para encontrar símbolos em bibliotecas dinâmicas, para as estáticas é necessário passá-las em ordem de dependência. Por exemplo, se seu programa usa a libpng.a que usa a libz.a internamente, o comando correto para linká-lo é:
gcc programa.c -oprograma /usr/lib/libpng.a /usr/lib/libz.a
Mas se a ordem estivesse invertida:
$ gcc programa.c -oprograma /usr/lib/libz.a /usr/lib/libpng.a /usr/lib/libpng.a(png.o): In function `png_reset_crc': undefined reference to `crc32' /usr/lib/libpng.a(png.o): In function `png_calculate_crc': undefined reference to `crc32' /usr/lib/libpng.a(png.o): In function `png_calculate_crc': undefined reference to `crc32' /usr/lib/libpng.a(png.o): In function `png_reset_zstream': undefined reference to `inflateReset' collect2: ld returned 1 exit status
Muito boa a dica, eu vivo apanhando para isso :)
As vezes é necessario alterar makefile (gerado com autoconf) dos programas que eu instalo na mão mesmo.
A ordem é importante, valeu a dica.
Também tem o caso de uma mesma função ser definida numa biblioteca e num outro arquivo objeto, mas isso é outra história.
Mas teu exemplo não é portável, é?
Não seria melhor usar:
-lpng -lz
para incluir as bibliotecas?
Certo, em uma situacao normal e’ melhor usar “-lpng -lz”. Mas nesse exemplo, a intencao era forcar o uso das bibliotecas estaticas (usando -l o linker vai pegar a dinamica, se existir) pra mostrar o erro :)
Me ajudou muito com a dica! Obrigado mesmo!