Forum: Compiler & IDEs Makefile, #defines und mehrere Ausgabedateien


von Bernhard L. (bernhard_r84)


Lesenswert?

Guten Morgen!

Ich möchte freundlich um Hinweise bitten mit der ich die Lösung für ein 
Problem im Zusammenhang mit einem Makefile komme.

Hintergrund:
================

Ich nutze für meine AVR-Projekte immer das Beispiel-Makefile von 
http://www.mikrocontroller.net/articles/Beispiel_Makefile
Das klappt einwandfrei bei kleineren Projekten mit einer einheitlichen 
Hardware-Plattform.

Jetzt arbeite ich aber an einem größeren Projekt bei dem es verschiedene 
Hardware-Revisionen mit jeweils anderen Features und Funktionen gibt.

Die Unterscheidung für welche Hardware der Code compiliert wird, mache 
ich anhand von vielen Präprozessor #ifdef Anweisungen direkt im C 
Quellcode.
Außerdem wird im Makefile je nach Hardware der ein oder andere Quellcode 
mit hinzugefügt.

Aktuell in der Entwicklung ist es gerade kein Problem im Makefile direkt 
anzugeben mit welcher Hardware ich gerade arbeite.

Konkrete Frage:
================

Nun suche ich nach einer Möglichkeit das Erzeugen von einer Variante 
(während der Arbeit an einer Hardware) und das automatisierte Erzeugen 
von Hex-Files jeder einzelnen Variante automatisiert durchzuführen.

z.B. sollte ein einfacher Aufruf von "make" sämtliche Varianten erzeugen 
(davor immer ein "make clean"), das Hex-File "hw1_chip1.hex" nennen und 
dieses im Unterverzeichnis "release" ablegen

"make hw1_chip1" würde dann nur eine Variante erzeugen und diese z.B. 
main.hex o.ä. im aktuellen Verzeichnis nennen.

Dabei stehe ich etwas auf der Leitung da ich nicht weiß wo ich wie 
anfangen bzw. nach was ich suchen soll.

Hier der aktuell von mir angepasste Ausschnitt aus dem Makefile mit dem 
ich aktuell noch arbeite:
1
# HW1, HW2 or HW3
2
TARGET_DEVICE = HW1
3
# CHIP1, CHIP2 or CHIP3
4
CHIP_TYPE = CHIP1
5
6
F_CPU = 20000000
7
8
# HW1 and HW2 with CHIP1 are running at 16MHz
9
ifeq ($(CHIP_TYPE), CHIP1)
10
ifeq ($(TARGET_DEVICE), HW1)
11
F_CPU = 16000000
12
endif
13
ifeq ($(TARGET_DEVICE), HW2)
14
F_CPU = 16000000
15
endif
16
endif
17
18
# List C source files here. (C dependencies are automatically generated.)
19
SRC = main.c driver.c led.c usb.c twim_int.c aes.c
20
21
ifeq ($(TARGET_DEVICE), HW1)
22
USE_IOEXP = YES
23
USE_KEYBOARD = YES
24
endif
25
26
ifeq ($(TARGET_DEVICE), HW2)
27
USE_KEYBOARD = YES
28
endif
29
30
ifeq ($(TARGET_DEVICE), HW3)
31
USE_IOEXP = YES
32
endif
33
34
35
ifeq ($(USE_KEYBOARD), YES)
36
SRC += kbd.c
37
endif
38
39
ifeq ($(USE_IOEXP), YES)
40
SRC += pca955x.c
41
endif
42
43
ifeq ($(CHIP_TYPE), CHIP1)
44
SRC += chip1drv.c
45
endif
46
47
ifeq ($(CHIP_TYPE), CHIP2)
48
SRC += chip2drv.c chip2util.c
49
endif
50
51
ifeq ($(CHIP_TYPE), CHIP3)
52
SRC += chip3drv.c chip3util.c
53
endif

Bin für jeden zielführenden Hinweis sehr dankbar :)

Grüße,
Bernhard

von Markus F. (mfro)


Lesenswert?

Bernhard L. R. schrieb:
> Bin für jeden zielführenden Hinweis sehr dankbar :)

Ich mache für ein recht umfangreiches Projekt (kein AVR) so was 
ähnliches (ein Makefile für mehrere Plattformen, Quellen in einem 
gemeinsamen Source tree) mit Templates. Ein (gekürzter) Ausschnitt aus 
dem Makefile:
1
TRGTDIRS=./target1 ./target2 ./target3
2
EXE=program
3
4
CSRCS=\
5
    sysinit.c \
6
    init_fpga.c \
7
    fault_vectors.c \
8
    ...
9
    interrupts.c \
10
    pci.c
11
12
ASRCS=\
13
    start.S\
14
    exceptions.S
15
16
SRCS=$(ASRCS) $(CSRCS)
17
COBJS=$(patsubst %.c,%.o,$(CSRCS))
18
AOBJS=$(patsubst %.S,%.o,$(ASRCS))
19
OBJS=$(COBJS) $(AOBJS)
20
21
# flag targets
22
target1/$(EXE): MACHINE=MACHINE_TARGET1
23
target2/$(EXE): MACHINE=MACHINE_TARGET2
24
target3/$(EXE): MACHINE=MACHINE_TARGET3
25
26
#
27
# define pattern rules for object files
28
#
29
define CC_TEMPLATE
30
$(1)/objs/%.o:%.c
31
    $(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@
32
33
$(1)/objs/%.o:%.S
34
    $(CC) $$(CFLAGS) $(INCLUDE) -c $$< -o $$@
35
endef
36
$(foreach DIR,$(TRGTDIRS),$(eval $(call CC_TEMPLATE,$(DIR))))
37
38
#
39
# define pattern rules for binaries
40
#
41
define EX_TEMPLATE
42
# pattern rule for flash targets
43
$(1)_MAPFILE=$(1)/$$(basename $$(EXE)).map
44
$(1)/$$(EXE): $(LDCSRC)
45
    $(CPP) $(INCLUDE) -DOBJDIR=$(1)/objs -P -DFORMAT_ELF=$(FORMAT_ELF) -D$$(MACHINE) $(LDCSRC) -o $(1)/$$(LDCFILE)
46
    $(LD) --oformat $$(FORMAT) -Map $$($(1)_MAPFILE) --cref -T $(1)/$$(LDCFILE) -o $$@
47
    $(OBJCOPY) -O srec $$@ $$(basename $$@).s19
48
endif
49
endef
50
$(foreach DIR,$(TRGTDIRS),$(eval $(call EX_TEMPLATE,$(DIR))))
Die Idee ist, daß die Objekte und Executables in für jedes Ziel 
getrennten, ansonsten aber (strukturell) identischen Verzeichnissen 
abgelegt werden. Die Templates erzeugen für jedes dieser 
Zielverzeichnisse individuelle Regeln, die abhängig vom Target (s. 
Definition von $(MACHINE) bei "flag targets") unterschiedliche 
Präprozessor-Definitionen enthalten können.

[edit: da war noch ein Fehler drin]

: Bearbeitet durch User
von sebastians (Gast)


Lesenswert?

Vielleicht hilft dir das weiter:

http://www.gnu.org/software/make/manual/html_node/Target_002dspecific.html#Target_002dspecific

ich hab mal drüber nachgedacht, das zu verwenden, hab aber keine gute 
Idee gehabt, wie ich das übersichtlich halten kann.

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.