Je suis nouveau sur Linux OS. J'essaie de compiler un fichier .c
à l'aide d'un fichier makefile. La bibliothèque de mathématiques doit être liée. Mon fichier make ressemble à ceci:
CC=gcc
CFLAGS=-Wall -lm
all:client
.PHONY: clean
clean:
rm *~ *.o client
Lorsque je lance make
, j'obtiens le message d'erreur suivant:
"undefined reference to rint"
Donc, il n'est pas capable de lier la bibliothèque de mathématiques.
Mais quand je compile explicitement en utilisant
gcc client.c -lm -o client
il compile avec succès.
Alors, comment devrais-je changer mon makefile pour qu'il fonctionne? J'ai déjà essayé d'ajouter LDFLAGS=-lm
. Mais je reçois la même erreur.
Je devrais aussi ajouter que lorsque je lance make
, il se développe en
gcc -Wall -lm client.c -o client
(remarquez que lorsque je lance gcc
explicitement avec -lm
à la fin, cela fonctionne).
Votre éditeur de liens (ld) n'aime évidemment pas l'ordre dans lequel make arrange les arguments de GCC, vous devrez donc changer un peu votre Makefile:
CC=gcc
CFLAGS=-Wall
LDFLAGS=-lm
.PHONY: all
all: client
.PHONY: clean
clean:
$(RM) *~ *.o client
OBJECTS=client.o
client: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS)
Dans la ligne définissant la cible client, modifiez l'ordre de $ (LDFLAGS) selon vos besoins.
Dans des scénarios de compilation plus complexes, il est courant de scinder la compilation en étapes, la compilation et l’assemblage se déroulant d’abord (sortie dans des fichiers objet), puis de lier les fichiers objet à un exécutable final ou à une bibliothèque, ce qui évite de recompiler tous les fichiers objet leurs fichiers sources n'ont pas changé. C'est pourquoi l'inclusion de l'indicateur de liaison -lm
ne fonctionne pas lorsque vous le mettez dans CFLAGS
(CFLAGS
est utilisé dans la phase de compilation).
La convention pour les bibliothèques à lier 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 de devoir écrire votre propre règle de liaison. Pour les autres marques, il devrait y avoir un drapeau pour sortir les règles intégrées (pour GNU make, il s'agit de -p
). Si votre version de make n'a pas de règle intégrée pour les liens (ou si elle n'a pas d'espace réservé pour les directives -l
), vous devrez écrire votre propre:
client.o: client.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_Arch) -c -o $@ $<
client: client.o
$(CC) $(LDFLAGS) $(TARGET_Arch) $^ $(LOADLIBES) $(LDLIBS) -o $@
On dirait 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)
vient avec Centos-6.7 satisfait de l'option de l'éditeur de liens avant inputfile; mais gcc avec Ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413
ne le permet pas.
Ce n'est pas la version gcc seule, j'ai quelque chose à faire avec les distributions