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).
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.
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 $@
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