Suche…


Erstellen von verschiedenen Quellordnern in verschiedene Zielordner

Hauptmerkmale dieses Makefiles:

  • Automatische Erkennung von C-Quellen in angegebenen Ordnern
  • Mehrere Quellordner
  • Mehrere entsprechende Zielordner für Objekt- und Abhängigkeitsdateien
  • Automatische Regelgenerierung für jeden Zielordner
  • Erstellung von Zielordnern, wenn diese nicht vorhanden sind
  • Abhängigkeitsmanagement mit gcc : Bauen Sie nur das Notwendigste auf
  • Funktioniert auf Unix und DOS Systemen
  • Geschrieben für GNU Make

Dieses Makefile kann verwendet werden, um ein Projekt mit einer solchen Struktur zu erstellen:

\---Project
    +---Sources
    |   +---Folder0
    |   |       main.c
    |   |       
    |   +---Folder1
    |   |       file1_1.c
    |   |       file1_1.h
    |   |       
    |   \---Folder2
    |           file2_1.c
    |           file2_1.h
    |           file2_2.c
    |           file2_2.h
    \---Build
        |   Makefile
        |   myApp.exe
        |   
        +---Folder0
        |       main.d
        |       main.o
        |       
        +---Folder1
        |       file1_1.d
        |       file1_1.o
        |       
        \---Folder2
                file2_1.d
                file2_1.o
                file2_2.d
                file2_2.o

Makefile

# Set project directory one level above of Makefile directory. $(CURDIR) is a GNU make variable containing the path to the current working directory
PROJDIR := $(realpath $(CURDIR)/..)
SOURCEDIR := $(PROJDIR)/Sources
BUILDDIR := $(PROJDIR)/Build

# Name of the final executable
TARGET = myApp.exe

# Decide whether the commands will be shwon or not
VERBOSE = TRUE

# Create the list of directories
DIRS = Folder0 Folder1 Folder2
SOURCEDIRS = $(foreach dir, $(DIRS), $(addprefix $(SOURCEDIR)/, $(dir)))
TARGETDIRS = $(foreach dir, $(DIRS), $(addprefix $(BUILDDIR)/, $(dir)))

# Generate the GCC includes parameters by adding -I before each source folder
INCLUDES = $(foreach dir, $(SOURCEDIRS), $(addprefix -I, $(dir)))

# Add this list to VPATH, the place make will look for the source files
VPATH = $(SOURCEDIRS)

# Create a list of *.c sources in DIRS
SOURCES = $(foreach dir,$(SOURCEDIRS),$(wildcard $(dir)/*.c))

# Define objects for all sources
OBJS := $(subst $(SOURCEDIR),$(BUILDDIR),$(SOURCES:.c=.o))

# Define dependencies files for all objects
DEPS = $(OBJS:.o=.d)

# Name the compiler
CC = gcc

# OS specific part
ifeq ($(OS),Windows_NT)
    RM = del /F /Q 
    RMDIR = -RMDIR /S /Q
    MKDIR = -mkdir
    ERRIGNORE = 2>NUL || true
    SEP=\\
else
    RM = rm -rf 
    RMDIR = rm -rf 
    MKDIR = mkdir -p
    ERRIGNORE = 2>/dev/null
    SEP=/
endif

# Remove space after separator
PSEP = $(strip $(SEP))

# Hide or not the calls depending of VERBOSE
ifeq ($(VERBOSE),TRUE)
    HIDE =  
else
    HIDE = @
endif

# Define the function that will generate each rule
define generateRules
$(1)/%.o: %.c
    @echo Building $$@
    $(HIDE)$(CC) -c $$(INCLUDES) -o $$(subst /,$$(PSEP),$$@) $$(subst /,$$(PSEP),$$<) -MMD
endef

.PHONY: all clean directories 

all: directories $(TARGET)

$(TARGET): $(OBJS)
    $(HIDE)echo Linking $@
    $(HIDE)$(CC) $(OBJS) -o $(TARGET)

# Include dependencies
-include $(DEPS)

# Generate rules
$(foreach targetdir, $(TARGETDIRS), $(eval $(call generateRules, $(targetdir))))

directories: 
    $(HIDE)$(MKDIR) $(subst /,$(PSEP),$(TARGETDIRS)) $(ERRIGNORE)

# Remove all objects, dependencies and executable files generated during the build
clean:
    $(HIDE)$(RMDIR) $(subst /,$(PSEP),$(TARGETDIRS)) $(ERRIGNORE)
    $(HIDE)$(RM) $(TARGET) $(ERRIGNORE)
    @echo Cleaning done ! 

So verwenden Sie dieses Makefile Um dieses Makefile an Ihr Projekt anzupassen, müssen Sie:

  1. Ändern Sie die TARGET Variable entsprechend Ihrem Zielnamen
  2. Ändern Sie den Namen der Sources und Build - Ordner in SOURCEDIR und BUILDDIR
  3. Ändern Sie die Ausführlichkeitsstufe des Makefiles im Makefile selbst oder beim Aufruf von make
  4. Ändern Sie den Namen der Ordner in DIRS entsprechend Ihren Quellen und Erstellungsordnern
  5. Ändern Sie bei Bedarf den Compiler und die Flags

Listen mit Zippern

GNU machen

Diese pairmap Funktion benötigt drei Argumente:

  1. Ein Funktionsname
  2. Erste durch Leerzeichen getrennte Liste
  3. Zweite durch Leerzeichen getrennte Liste

Für jedes gezippte Tupel in den Listen wird die Funktion mit den folgenden Argumenten aufgerufen:

  1. Tupel-Element aus der ersten Liste
  2. Tupel-Element aus der zweiten Liste

Es wird zu einer durch Leerzeichen getrennten Liste der Funktionserweiterungen erweitert.

list-rem = $(wordlist 2,$(words $1),$1)
pairmap = $(and $(strip $2),$(strip $3),$(call \
    $1,$(firstword $2),$(firstword $3)) $(call \
    pairmap,$1,$(call list-rem,$2),$(call list-rem,$3)))

Zum Beispiel das:

LIST1 := foo bar baz
LIST2 := 1 2 3

func = $1-$2

all:
    @echo $(call pairmap,func,$(LIST1),$(LIST2))

.PHONY: all

Druckt foo-1 bar-2 baz-3 .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow