Forum: Compiler & IDEs Makefile erzeugt .o-Datei nicht


von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich nutze make, um ein PC-Programm (in C) zu erzeugen. "Besonderheit" 
ist, daß einzelne C-Dateien in der Verzeichnisstruktur "doppelt" 
vorkommen (nämlich einmal im Ordner "common", einmal im Ordner 
"project". Ist dies der Fall, soll die Datei im Ordner "project" immer 
Vorrang haben, die gleichnamige Datei im Ordner "common" also ignoriert 
werden.

Ich habe dazu das angehängte Makefile zusammengedengelt. Es ist ein 
wenig länger, als es für das Mini-Projekt im Beispiel (in dem das 
gleiche Makefile auch enthalten ist) nötig wäre, weil im 
Original-Projekt noch die Aufgabe hinzukommt, gegen die SDL2-Library zu 
linken und die aktuelle Versionsnummer aus dem Versionsverwaltungssystem 
zu holen. Letzteres ist auch noch ein Problem - aber das ist jetzt 
nicht die Fragestellung.

Im Anhang befindet sich ein kompilierbares Mini-Beispiel, das auch 
korrekt funktioniert. Allerdings werden im Ordner des Makefiles 
("mockup") keine Dateien "comp2.o/comp2.d, "comp3.o/comp3.d" erzeugt. 
Stattdessen entsteht eine Datei "gmon.out", nach der ich nie gefragt 
habe.

Ich nutze GNU make und die MinGW-Toolchain.

 - Wo landen meine o.-Dateien?
 - Gibt es eine sinnvollere Lösung, einem Verzeichnis den Vorzug 
gegenüber einem anderen zu geben?



Viele Grüße
W.T.

P.S.: Es ist mir auch bewußt, daß das Makefile an den folgenden 
Klassiker erinnert: https://xkcd.com/1513/ . Es nützt nur nichts. Auch 
nach zwei O'Reilly-Büchern über Make will sich mir diese Sprache nicht 
erschließen.

von Markus F. (mfro)


Lesenswert?

Ich würde das einfach mit VPATH lösen.

Du hast VPATH zwar benutzt, aber - entgegen deinen eigenen Anforderungen 
- verkehrt herum.

Dreh' die Reihenfolge der Pfadelemente um und ein Fehler ist schon 
ausgemerzt.

von Walter T. (nicolas)


Lesenswert?

Markus F. schrieb:
> Du hast VPATH zwar benutzt, aber - entgegen deinen eigenen Anforderungen
> - verkehrt herum.

Oha, also definiert die Variable VPATH eine Suchreihenfolge. Das ist ja 
famos!

Danke für die Antwort!

von Jay (Gast)


Lesenswert?

Walter T. schrieb:
> Hallo zusammen,
>
> ich nutze make, um ein PC-Programm (in C) zu erzeugen. "Besonderheit"
> ist, daß einzelne C-Dateien in der Verzeichnisstruktur "doppelt"
> vorkommen (nämlich einmal im Ordner "common", einmal im Ordner
> "project". Ist dies der Fall, soll die Datei im Ordner "project" immer
> Vorrang haben, die gleichnamige Datei im Ordner "common" also ignoriert
> werden.
>
> Ich habe dazu das angehängte Makefile zusammengedengelt. Es ist ein
> wenig länger, als es für das Mini-Projekt im Beispiel (in dem das
> gleiche Makefile auch enthalten ist) nötig wäre, weil im
> Original-Projekt noch die Aufgabe hinzukommt, gegen die SDL2-Library zu
> linken und die aktuelle Versionsnummer aus dem Versionsverwaltungssystem
> zu holen. Letzteres ist auch noch ein Problem - aber das ist jetzt
> nicht die Fragestellung.
>
> Im Anhang befindet sich ein kompilierbares Mini-Beispiel, das auch
> korrekt funktioniert. Allerdings werden im Ordner des Makefiles
> ("mockup") keine Dateien "comp2.o/comp2.d, "comp3.o/comp3.d" erzeugt.
> Stattdessen entsteht eine Datei "gmon.out", nach der ich nie gefragt
> habe.

Doch, hast du. Wer Profiling einschaltet bekommt Profiling-Output:
1
CFLAGS = -g -pg -Wall -Wextra -Wpedantic -std=c99\
2
  -Wsign-conversion -DGLCD_FRAMEBUFFER -DPLATFORM_PC

>  - Wo landen meine o.-Dateien?

Wo du sie mit -o halt hinschreibst.

>  - Gibt es eine sinnvollere Lösung, einem Verzeichnis den Vorzug
> gegenüber einem anderen zu geben?

1. Rekursives Make-System verwenden, in die jeweiligen 
Source-Verzeichnisse reingehen. Dabei bestimmst du die Reihenfolge wie 
in die Verzeichnisse gegangen wird.

Ja, es gibt ein Idioten-Pamphlet, das gerne zitiert wird, wonach die 
rekursive Verwendung von Make eine schlechte Idee ist. Kannst du 
vergessen.

2. Für jedes Source-Verzeichnis im Makefile des Verzeichnisses die 
Quellen (.c Dateien) auflisten. Die, genau die, und nur die. Daraus auch 
eine Liste der .o-Dateien bauen.

2a. In jenem Verzeichnis mit der doppelten Datei eben jene Datei nicht 
im Makefile aufzählen.

VPATH ist so eine Sache. Meist kann man es nicht gebrauchen, aber hier 
könnte es gehen. Allerdings vermeide ich VPATH, weil man eigentlich 
keine echte Kontrolle mehr darüber hat, was wirklich in eine Software 
reinkompiliert wird.

VPATH funktioniert am besten, wenn man in dem Verzeichnis ist, in 
welches die .o geschrieben werden soll. Dann kann man mit VPATH ein 
weites Netz auswerfen um irgendwo die .c-Datei für die zu bauende 
.o-Datei zu suchen. VPATH ist allerdings ein Pfad von Verzeichnissen, 
man kann damit nicht direkt einzelne Dateien selektieren. VPATH geht 
daher z.B. dann schief, wenn die Priorität der Verzeichnisse nicht für 
jede Datei gleich ist.

Damit make allerdings auf die Idee kommt, eben jene .o-Datei zu bauen 
muss sie irgendwo als Abhängigkeit deklariert sein. Eine Wildcard oder 
Pattern reicht da nicht. Da muss schon irgendwo der echte Name stehen 
oder per Rule aus z.B. einer namentlich aufgeführten .c ableitbar sein.

> P.S.: Es ist mir auch bewußt, daß das Makefile an den folgenden
> Klassiker erinnert: https://xkcd.com/1513/ . Es nützt nur nichts. Auch
> nach zwei O'Reilly-Büchern über Make will sich mir diese Sprache nicht
> erschließen.

Es ist eine deklarative, regelbasierte Sprache. Wenn du versuchst sie, 
wie in deinem Makefile, funktional zu verwenden geht das schief. Von so 
einem Zeug wie ifdef würde ich als Anfänger die Finger lassen. Erst mal 
für einen Fall die Regeln richtig hinbekommen.

von Eric B. (beric)


Lesenswert?

Jay schrieb:
> 1. Rekursives Make-System verwenden, in die jeweiligen
> Source-Verzeichnisse reingehen. Dabei bestimmst du die Reihenfolge wie
> in die Verzeichnisse gegangen wird.
>
> Ja, es gibt ein Idioten-Pamphlet, das gerne zitiert wird, wonach die
> rekursive Verwendung von Make eine schlechte Idee ist. Kannst du
> vergessen.

Das Paper heisst "recursive Make considered harmful" [1] und listet 
einige gute Gründe auf wonahc man rekursives Make besser vermeidet. Aber 
wie bei allen solchen "Rezepten", soll man sich überlegen ob es für das 
eigene Projekt zutrifft oder eben nicht. Das ganze als 
"Idioten-Pamphlet" abzuwinken ist ein wenig kurzsichtig.

Ich habe vor nicht zu lange zeit ein mittelgroßes Projekt (~ 400 
C-Dateien in etwa 40 Komponenten/Verzeichnissen) ziemlich erfolgreich 
mit dem Ansatz aus dem Paper umsetzen können. Und das war um einiges 
besser wartbar und erweierbar als mit rekursive Makefiles möglich 
gewesen wäre.


[1] http://aegis.sourceforge.net/auug97.pdf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.