2010-07-16 15 views
12

Ich bin nicht makefiles, aber bin gewöhnt an einfache. Im Moment habe ich eine Aufgabe zur Hand.Makefile - ändere den Variablenwert in Abhängigkeit von einem Ziel

Ich muss eine Testanwendung mit einer anderen Bibliothek und einem anderen Include-Pfad basierend auf dem angegebenen Ziel kompilieren und verknüpfen. Wenn das Ziel TARGET1 ist, verknüpfen Sie es mit LIB1 und fügen Sie INCLUDEPATH1 während der Kompilierung ein. Wenn das Ziel TARGET2 ist, kompilieren Sie es mit INCLUDEPATH2 in CFLAGS und verknüpfen Sie es mit LIB2.

Jetzt habe ich eine Regel wie oben, die meine Testanwendung kompiliert. Nun, wie können die CFLAGS basierend auf dem Ziel geändert werden.

Antwort

27

Wenn Sie mit GNU Make, können Sie target-specific variables verwenden:

target1: CFLAGS = -IINCLUDEPATH1 
target1: LDLIBS = -lLIB1 

target2: CFLAGS = -IINCLUDEPATH2 
target2: LDLIBS = -lLIB2 

all: target1 target2 

target1: target1.o misc.o 
target2: target2.o 

jedoch nicht ganz so gut funktioniert, wie Sie möchten: wenn target1 und target2 Aktien einige Quelldateien , müssen Sie dafür sorgen, dass sie jeweils zweimal kompiliert werden und zu anders benannten .o-Dateien - was Ihr Makefile eher komplexiert.

Auch, wenn Sie geben make target1 dann -IINCLUDEPATH1 wird auf die Erstellung von misc.c, je nach Wunsch vermehrt werden. Jedoch, wenn Sie make misc.o eingeben es hat keine Möglichkeit zu wissen, dass dies schließlich für target1 bestimmt ist und die Kompilation von misc.c wird keinen speziellen $ CFLAGS-Wert erhalten (obwohl es den globalen erhalten wird, wenn es einen gibt).

Das ist also wirklich nur in einfachen Fällen sinnvoll. Aber vielleicht ist Ihr Fall einfach genug.

+1

Wow, ich wusste nicht, dass zielspezifische Variablen zu impliziten Regeln propagiert werden! –

+0

Toller Rat. Obwohl ich Makefiles zu lange geschrieben habe, war mir dieses Feature irgendwie nie bewusst. –

1

Ich glaube nicht, dass Sie Variable abhängig von einem Ziel ändern können. Angenommen, Sie

make TARGET1 TARGET2 

aufrufen Welchen Wert würde die CFLAGS haben dann?

In diesem Fall können Sie Nicht-Musterregeln verwenden, um Ziele zu unterscheiden.

TARGET1: a.c 
    @echo [CC] $< ... 
    $(CC) -I INCLUDEPATH1 ... 

TARGET2: a.c 
    @echo [CC] $< ... 
    $(CC) -I INCLUDEPATH2 ... 

Um Wiederholungen zu verringern, können Sie auch Variablen verwenden und "functions". Dann könnten Sie den Körper Ihrer Musterregel in verschiedenen Regeln wiederverwenden.

define compile_cmd 
    @echo [CC] $< ... 
    $(CC) -I $1 -l$2 $(CFLAGS) 
endef 

TARGET1: a.c 
    $(call compile_cmd,INCLUDEPATH1,LIB1) -o [email protected] $< 

TARGET2: a.c 
    $(call compile_cmd,INCLUDEPATH2,LIB2) -o [email protected] $< 

%.o: %.c 
    $(call compile_cmd,INCLUDEPATH_DEFAULT,LIB_DEFAULT) -o [email protected] $< 

Das würde ein nettes und flexibles Makefile machen, das Ihren Bedürfnissen entspricht.

Verwandte Themen