2010-03-07 14 views
19

Estoy intentando compilar un proyecto que usa tanto libjpeg como libpng. Sé que libpng necesita zlib, así que compilé los tres independientemente y los puse (libjpeg.a, libpng.a y libz.a) en una carpeta llamada linrel32. Lo que yo haga a continuación es:Enlazando con libpng & zlib?

g++ -Llinrel32/ program.cpp otherfile.cpp -o linrel32/executable -Izlib/ -Ilpng140/ -Ijpeg/ -lpthread -lX11 -O2 -DLINUX -s -lz -lpng -ljpeg

Así que incluyen las tres bibliotecas. Aún así, el enlazador se queja:

linrel32//libpng.a(png.o): In function `png_calculate_crc': 
png.c:(.text+0x97d): undefined reference to `crc32' 
linrel32//libpng.a(png.o): In function `png_reset_crc': 
png.c:(.text+0x9be): undefined reference to `crc32' 
linrel32//libpng.a(png.o): In function `png_reset_zstream': 
png.c:(.text+0x537): undefined reference to `inflateReset' 
linrel32//libpng.a(pngread.o): In function `png_read_destroy': 
pngread.c:(.text+0x6f4): undefined reference to `inflateEnd' 
linrel32//libpng.a(pngread.o): In function `png_read_row': 
pngread.c:(.text+0x1267): undefined reference to `inflate' 
linrel32//libpng.a(pngread.o): In function `png_create_read_struct_2': 

(... usted consigue la idea: D)

collect2: ld returned 1 exit status 

sé las funciones que faltan son de zlib, y estoy añadiendo zlib allí. Abrió libz.a y parece tener una buena estructura. Lo volvió a compilar, todo se ve bien. Pero no es ...

No lo sé, es probable que el problema sea trivial, y lo que necesito es dormir un rato. Pero aún así, si usted podría ayudarme a averiguar esta cosa ...

Respuesta

38

necesita reordenar el orden de la bibliotecas:

-lpng -ljpeg -lz 

Lo que está sucediendo es que el enlazador tiene reglas especiales sobre cómo trata las bibliotecas estáticas. Lo que hace es que solo incluye un .o desde adentro del .a si el .o es necesario para satisfacer una referencia.

Además, maneja los archivos estáticos en el orden en que aparecen en la línea del enlace.

Por lo tanto, su código no llama directamente a ninguna función en zlib. Por lo tanto, cuando el vinculador maneja -lz primero, todavía no hay llamadas, por lo que no extrae ninguna de zlib.

A continuación, cuando el vinculador maneja libpng, ve que hay llamadas desde su código. Por lo tanto, extrae el código de libpng y, como hace llamadas a zlib, ahora hay referencias a las funciones de zlib.

Ahora llega al final de sus bibliotecas y hay llamadas insatisfechas que causan su error.

lo tanto, si libhigh.a hace uso de liblow.a, debe tener -lhighantes-llow en el orden de enlace.

+1

Gracias. Estás absolutamente en lo correcto. Consideré que la orden era una posibilidad, pero no tenía ninguna razón real para apoyar esa teoría. Erróneamente pensé que el enlazador puso todo en un 'grupo', y luego eliminó las funciones no utilizadas después de rastrear cada fragmento de código. – huff

+0

@huff - de nada. FYI, el orden solo importa para los archivos estáticos; si usaste objetos compartidos, no importaría. –

+0

Ahora mezcle, p. CMake y la diversión es aún mayor (especialmente antes de pasar VERBO = 1 para hacer). ¿Es zlib una biblioteca estática? Tengo un problema similar con boost :: iostreams que dependen de zlib; falla en mi máquina pero no en otras.De todos modos, esta es una buena regla general, las dependencias más "básicas" son las últimas. –

-2

es probable que necesite para rodear los encabezados zlib y png con extern "C", por ejemplo:

extern "C" { 
#include <zlib.h> 
} 
+3

Eso es incorrecto. Si ese fuera el caso, vería errores como 'referencia indefinida a:" crc32 (unsigned long, char const *, unsigned int) "' y no solo 'undefined reference to:" crc32 "' –

+0

+1 para corregirme. –