Comment utiliser LDFLAGS dans makefile

Je suis nouveau sur Linux OS. J'essaie de compiler un fichier .c en utilisant un makefile. La bibliothèque mathématique doit être liée. Mon makefile ressemble à ceci:

CC=gcc
CFLAGS=-Wall -lm

all:client

.PHONY: clean
clean:
    rm *~ *.o client

Quand je lance make, j'obtiens l'erreur suivante:

"undefined reference to rint"

Il N'est donc pas capable de lier la bibliothèque mathématique.

Mais quand je compile explicitement en utilisant

gcc client.c -lm -o client

Il compile avec succès.

Alors, comment dois-je changer mon makefile de sorte qu'il fonctionne. J'ai déjà essayé d'ajouter LDFLAGS=-lm. Mais je reçois la même chose erreur.

Je devrais également ajouter que lorsque je lance make, il se développe à

gcc -Wall -lm client.c -o client

(notez que lorsque je lance gcc explicitement avec -lm à la fin, cela fonctionne).

54
demandé sur Stefan van den Akker 2012-11-06 15:03:10

3 réponses

Votre éditeur de liens (ld) n'aime évidemment pas l'ordre dans lequel make organise les arguments GCC, donc vous devrez changer un peu votre Makefile:

CC=gcc
CFLAGS=-Wall
LDFLAGS=-lm

.PHONY: all clean

all: client

clean:
    $(RM) *~ *.o client

OBJECTS=client.o
client: $(OBJECTS)
    $(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS)

Dans la ligne définissant la cibleclient , modifiez l'ordre de $(LDFLAGS) selon les besoins.

55
répondu Makkes 2018-09-24 18:49:38

Dans les scénarios de construction plus compliqués, il est courant de diviser la compilation en étapes, la compilation et l'assemblage se produisant en premier (sortie vers les fichiers objet), et de lier les fichiers objet dans un exécutable final ou une bibliothèque par la suite-cela évite de recompiler tous les fichiers objet lorsque leurs fichiers source n'ont pas changé. C'est pourquoi l'inclusion du drapeau de liaison -lm ne fonctionne pas lorsque vous le mettezCFLAGS (CFLAGS est utilisé dans l'étape de compilation).

La convention pour que les bibliothèques soient linked est de les placer dans LOADLIBES ou LDLIBS (GNU make inclut les deux, mais votre kilométrage peut varier):

LDLIBS=-lm

Cela devrait vous permettre de continuer à utiliser les règles intégrées plutôt que d'avoir à écrire votre propre reliant la règle. Pour les autres marques, il devrait y avoir un drapeau pour afficher les règles intégrées (pour GNU make, c'est -p). Si votre version de make n'a pas de règle intégrée pour la liaison (ou si elle n'a pas d'espace réservé pour les directives -l), vous devrez écrire la vôtre:

client.o: client.c
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<

client: client.o
    $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
45
répondu laindir 2012-11-06 15:01:02

Semble que l'ordre des drapeaux de liaison n'était pas un problème dans les anciennes versions de gcc. Par exemple gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16) est livré avec Centos-6.7 heureux avec l'option linker avant inputfile; mais gcc avec ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413 ne permet pas.

Ce n'est pas la version gcc seule, j'ai quelque chose à faire avec les distributions

1
répondu J.Greg 2016-08-10 04:07:09