web-dev-qa-db-fra.com

C: Création d'une bibliothèque statique et liaison à l'aide d'un Makefile

J'essaie de comprendre les bibliothèques statiques et partagées .

Je veux faire ce qui suit pour créer un makefile qui fait une compilation et une liaison séparées de telle sorte qu'une bibliothèque statique soit créée et liée pour former l'exécutable statique final.

J'ai le code suivant pour le Makefile, mais j'obtiens l'erreur suivante

Makefile:13: *** missing separator. Stop.

Mais j'essaie également de comprendre comment lier/créer des bibliothèques.

Si j'exécute les commandes après line 12 dans le terminal, ils fonctionnent, mais pas dans le makefile.

myProgram: main.o addSorted.o freeLinks.o
    gcc -lm -o myProgram main.o addSorted.o freeLinks.o

main.o: main.c
    gcc -O -c -lm main.c main.h

addSorted.o: addSorted.c addSorted.h
    gcc -O -c -lm addSorted.c

freeLinks.o: freeLinks.c freeLinks.h
    gcc -O -c -lm freeLinks.c

ar rc libmylib.a main.o addSorted.o freeLinks.o    //Error Line

ranlib libmylib.a

gcc -o foo -L. -lmylib foo.o

clean:
    rm -f myProgram main.o addSorted.o freeLinks.o

De plus, si vous pouvez aider à améliorer le code, je l'apprécierais vraiment.

15
user3337714

Essaye ça:

all: myProgram

myProgram: main.o libmylib.a #libmylib.a is the dependency for the executable
        gcc -lm -o myProgram main.o -L. -lmylib

main.o: main.c
        gcc -O -c main.c main.h

addSorted.o: addSorted.c addSorted.h
        gcc -O -c addSorted.c

freeLinks.o: freeLinks.c freeLinks.h
        gcc -O -c freeLinks.c

libmylib.a: addSorted.o freeLinks.o #let's link library files into a static library
        ar rcs libmylib.a addSorted.o freeLinks.o

libs: libmylib.a

clean:
        rm -f myProgram *.o *.a *.gch #This way is cleaner than your clean

Cet ensemble de règles compile d'abord tous les fichiers, puis il cible la bibliothèque (libmylib.a) et utilise son artefact pour lier l'exécutable. J'ai également ajouté un formulaire cible redondant séparé faisant uniquement des bibliothèques. Fichiers nécessaires:

user@Host> ls
addSorted.c  addSorted.h  freeLinks.c  freeLinks.h  main.c  main.h Makefile
19
Sergey

Un makefile n'est pas un script Shell. C'est un fichier de configuration pour un système expert. Plus précisément, un système expert qui sait, si vous le dites, comment créer efficacement des fichiers et leurs dépendances avec un minimum de fichiers à refaire qui n'ont pas besoin d'être refaits.

Si vous regardez la première règle que vous avez:

myProgram: main.o addSorted.o freeLinks.o
    gcc -lm -o myProgram main.o addSorted.o freeLinks.o

qui indique au système comment créer un fichier appelé "myProgram" s'il décide qu'il doit le faire. Les parties après les deux points sont des fichiers dont myProgram a besoin. S'ils ne sont pas là, ou s'ils décident qu'ils sont obsolètes, make essaiera de trouver une recette qui peut être utilisée pour les créer ou les mettre à jour. Une fois tout cela fait, make exécute ensuite la ligne "gcc ..." et suppose que cela créera ou mettra à jour myProgram.

Les lignes ar et ranlib que vous avez ne correspondent pas à la syntaxe requise pour une règle de makefile. De leur apparence, ils semblent être une recette pour faire libmylib.a. Si vous les mettez dans la syntaxe make doit le dire, vous obtenez:

libmylib.a: main.o addSorted.o freeLinks.o
    ar rcu libmylib.a main.o addSorted.o freeLinks.o
    ranlib libmylib.a

myProgram devrait dépendre de la bibliothèque elle-même, plutôt que du contenu de la bibliothèque, et il est préférable de mettre les options de bibliothèque à la fin:

myProgram: libmylib.a
    gcc -o myProgram libmylib.a -lm

si vous le souhaitez, vous pouvez utiliser une option pour indiquer à gcc de rechercher les bibliothèques dans le répertoire courant:

gcc -L. -o myProgram main.o -lmylib -lm

Il existe également des variables makefile qui peuvent vous aider à ne pas avoir à répéter autant, donc j'écrirais la première règle comme suit:

myProgram: libmylib.a
    gcc -L. -o $@ -lmylib -lm

cependant, il est peu probable que main.o fasse réellement partie de la bibliothèque, donc:

myProgram: main.o libmylib.a
    gcc -L. -o $@ $< -lmylib -lm

et la règle de bibliothèque comme:

libmylib.a: addSorted.o freeLinks.o
    ar rcu $@ $+
    ranlib $@

$ + ici signifie "tous les noms de fichiers de dépendances".

Enfin, si vous voulez que gcc crée un exécutable statique réel, et pas seulement utiliser la bibliothèque que vous avez créée, vous devez passer l'option '-static' à gcc.

5
user464502