Hilfe zu makefile

Gast #3643089
Lesenswert?

Hi,

für eine Anwendung habe ich mir ein eigenes makefile erzeugt. Die 
C-Dateien liegen in unterschiedlichen Verzeichnissen. Nun möchte ich,
dass die generierten OBJ-Dateien nicht da abgelegt werden wo sich die 
einzelnen C-Dateien befinden, sondern im Verzeichnis der Anwendung. Wie 
müsste ich die nachfolgenden Zeilen abändern?
1
%.obj: %.c
2
  $(COMPILER_PROGRAM) $(ASM_OPTIONS) $(C_OPTIONS) -c -o "$@" "$<"
Gast #3643099
Lesenswert?

Die OBJ-Dateien werden erzeugt, mit meinem makefile. Mir geht es nur 
darum, dass die OBJ-Dateien nicht im gleichen Verzeichnis wo sich auch 
die C-Dateien befinden, abgelegt werden.

Pfad Anwendung:

C:\Test\Projekt\OBJ\

Da sollen alle OBJ-Dateien abgelegt werden.
Gast #3643114
Lesenswert?

Entwickler schrieb:
> Nun möchte ich,
> dass die generierten OBJ-Dateien nicht da abgelegt werden wo sich die
> einzelnen C-Dateien befinden, sondern im Verzeichnis der Anwendung.

Starte den Makeaufruf in dem Verzeichnis, wo die Objektdateien landen 
sollen und benutze VPATH.

Siehe Regel 3 in http://mad-scientist.net/make/rules.html und vor allem 
http://mad-scientist.net/make/vpath.html
Persönliche Seite #3643234
Lesenswert?

Viel wichtiger als das Wie? ist das Warum? Makefiles enthalten auch 
einen clean-Aufruf, womit die Artefakte abgeräumt werden, die unterwegs 
entstanden. Es spricht nichts dagegen, nach der Erzeugung der Bibliothek 
oder des Programms die erstellten Artefakte abzuräumen (wenn das auch 
für zyklisches Bauen aus Versuch-Test-Korrektor-Goto Versuch Mist ist).
#3643245
Lesenswert?

Entwickler schrieb:
> einzelnen C-Dateien befinden, sondern im Verzeichnis der Anwendung. Wie
> müsste ich die nachfolgenden Zeilen abändern?
>
>
1
> %.obj: %.c
2
>   $(COMPILER_PROGRAM) $(ASM_OPTIONS) $(C_OPTIONS) -c -o "$@" "$<"
3
>

Den Namen des Zielobjektes gibst Du mittels der -o Option. Da ich die 
genaue Verzeichnisstruktur nicht kenne einfach mal ein Schuss ins blaue, 
muss entsprechend angepasst werden:
1
%.obj: %.c
2
  $(COMPILER_PROGRAM) $(ASM_OPTIONS) $(C_OPTIONS) -c -o "../OBJ/$@" "$<"

Bin allerdings nicht sicher, ob das Linken so funktionieren wird. Evtl. 
ist die Loesung mit VPATH besser.

ZigZeg
Gast #3643433
Lesenswert?

Ich mach's immer so:
1
# how is the final executable called?
2
exec = ...
3

4
# what modules are needed?
5
modules = ...
6

7
# what are the directories containing the source files?
8
VPATH = ...
9

10
# where should the objects be built?
11
builddir = ...
12

13

14
# what objects are needed
15
objects = $(addprefix $(builddir)/, $(addsuffix .o, $(modules)))
16

17

18
# how to build the executable
19
$(exec): $(objects)
20
  $(cc) -o $@ $^ $(lflags)
21

22
# how to compile objects
23
$(objects): $(builddir)/%.o: %.cpp
24
  $(cc) -c $(cflags) $(incl) -o $@ $<

Einfach alles ausfüllen (natürlich auch cc, cflags, lflags, incl etc.), 
Deine zu übersetzenden Source-Files trägst Du ohne Endung (.c, .cpp 
etc.) unter modules ein.
Gast #3643504
Lesenswert?

Boris Ohnsorg schrieb:
> Viel wichtiger als das Wie? ist das Warum?

Ein Grund wären zum Beispiel Backups. Ich habe in allem meinen Makefiles 
(na ja, in fast allen) eine kleines Skript, welches nach jedem (!) 
erfolgreichen Compiler-Lauf mittels eines einfachen find|cpio|bzip2 + 
timestamp ein Backup fährt. Das können je nach Situation full-, 
incremental- oder delta-Backups sein, meistens fahre ich nach einem 
erfolgreichen Unit-Test ein full-Backup, nach jedem Compiler-Lauf ein 
delta-Backup. Gerade letztere sind oft nur ein paar dutzend Kilobyte 
groß und genau die, die mir bisher die meisten Kopfschmerzen erspart 
haben. Natürlich geht das nur effizient, wenn man auf alles verzichtet, 
was groß und unnötig ist. Das trifft am ehesten auf Objektdateien zu, 
aber auch auf alles andere, was automatisch erzeugt wurde. (Man kann es 
ja jederzeit wieder erzeugen, die Quellen hat man ja.) Das geht am 
einfachsten, wenn man alles automatisch Erzeugte in ein eigenes 
Verzeichnis tut, welches man dann ganz einfach vom Backup ausschließen 
kann. Geht sicher auch anders, aber so am einfachsten. Außerdem lässt 
sich so einfacher aufräumen und es ist übersichtlicher.
Gast #3643535
Lesenswert?

Erstmal vielen Dank an alle!

Die OBJ-Dateien sollen im Projektordner unter obj abgelegt werden
--> C:\Test\Projekt\obj\

Bisher ist es mir nicht gelunden, dass die obj-Datein im Ordner obj 
abgelegt werden.
1
OBJ_FILES = MainApplication.obj \              ..\..\Lib\Can.obj \
2
    ..\..\Lib\Uart.obj
3

4
All: $(OBJ_FILES)
5
  $(COMPILER_PROGRAM) $(OBJ_FILES)
6

7
%.obj: %.c
8
  $(COMPILER_PROGRAM) $(CCOMPILER_OPTIONS) -c -o "$@" "$<"
Gast #3643580
Lesenswert?

Entwickler schrieb:
> Die OBJ-Dateien sollen im Projektordner unter obj abgelegt werden
> --> C:\Test\Projekt\obj\
>
> Bisher ist es mir nicht gelunden, dass die obj-Datein im Ordner obj
> abgelegt werden.
> OBJ_FILES = MainApplication.obj \              ..\..\Lib\Can.obj \
>     ..\..\Lib\Uart.obj
>
> All: $(OBJ_FILES)
>   $(COMPILER_PROGRAM) $(OBJ_FILES)
>
> %.obj: %.c
>   $(COMPILER_PROGRAM) $(CCOMPILER_OPTIONS) -c -o "$@" "$<"

Ja, wie denn auch? Das Verzeichnis C:\Test\Projekt\obj\ taucht im 
Makefile (wenigstens in dem Teil, den wir sehen) ja nicht einmal auf. 
..\..\Lib wird's ja wohl nicht sein.
#3643592
Lesenswert?

Entwickler schrieb:
> Sorry.
>
> Der Pfad wo die Lib-Dateien enthalten sind heißt:
>
> C:\Test\Lib\

Die Lösung wurde doch schon gepostet von Kai S.

Oder die VPATH Lösung.

Fragst du jetzt solange immer dasselbe bis jemand zu dir kommt und das 
für dich macht? Was hast du denn jetzt ausprobiert von den angegebenen 
Lösungen? Poste das mal? Kommen Fehlermeldungen? Oder was sonst?

gruß cyblord

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren