Cómo usar LDFLAGS en makefile
(3)
Soy nuevo en el sistema operativo Linux. Estoy intentando compilar un archivo .c
usando un archivo MAKE. La biblioteca de matemáticas tiene que estar vinculada. Mi archivo MAKE se ve así:
CC=gcc
CFLAGS=-Wall -lm
all:client
.PHONY: clean
clean:
rm *~ *.o client
Cuando ejecuto make
, obtengo el siguiente error:
"undefined reference to rint"
Por lo tanto, no puede vincular la biblioteca matemática.
Pero cuando compilo explícitamente usando
gcc client.c -lm -o client
compila con éxito.
Entonces, ¿cómo debería cambiar mi archivo MAKE para que funcione? Ya he intentado agregar LDFLAGS=-lm
. Pero obtengo el mismo error.
También debería agregar que cuando ejecuto make
, se expande a
gcc -Wall -lm client.c -o client
( -lm
en cuenta que cuando ejecuto gcc
explícitamente con -lm
al final, funciona).
En escenarios de compilación más complicados, es común dividir la compilación en etapas, primero la compilación y el ensamblaje (archivos de salida a objetos) y vincular los archivos de objetos en un ejecutable o biblioteca final; esto evita tener que recompilar todos los archivos de objeto cuando sus archivos fuente no han cambiado. Es por eso que incluir el -lm
enlace -lm
no funciona cuando lo coloca en CFLAGS
( CFLAGS
se usa en la etapa de compilación).
La convención para que las bibliotecas se vinculen es colocarlas en LOADLIBES
o LDLIBS
(la fabricación de GNU incluye ambas, pero su millaje puede variar):
LDLIBS=-lm
Esto debería permitirle continuar usando las reglas integradas en lugar de tener que escribir su propia regla de enlace. Para otras marcas, debería haber una bandera para generar reglas incorporadas (para GNU make, esto es -p
). Si su versión de make no tiene una regla incorporada para vincular (o si no tiene un marcador de posición para las directivas -l
), tendrá que escribir la suya propia:
client.o: client.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
client: client.o
$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
Su enlazador (ld) obviamente no le gusta el orden en que make organiza los argumentos de GCC, por lo que tendrá que cambiar su Makefile un poco:
CC=gcc
CFLAGS=-Wall
LDFLAGS=-lm
OBJECTS=client.o
client: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS)
all:client
.PHONY: clean
clean:
rm -f *~ *.o client
En la línea que define el objetivo del cliente , cambie el orden de $ (LDFLAGS) según sea necesario.
Parece que el orden de las banderas de enlace no era un problema en versiones anteriores de gcc. Por ejemplo, gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
viene con Centos-6.7 contento con la opción del enlazador antes del archivo de entrada; pero gcc con ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413
no permite.
No es solo la versión de gcc, tengo algo con las distribuciones