Tradičním způsobem je mít Makefile v každém z podadresářů (part1 , part2 , atd.), což vám umožní postavit je samostatně. Dále mějte Makefile v kořenovém adresáři projektu, který vše vytváří. "Root" Makefile bude vypadat nějak takto:
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Vzhledem k tomu, že každý řádek v cíli make je spuštěn ve svém vlastním shellu, není třeba se starat o procházení stromu adresářů nebo do jiných adresářů.
Doporučuji podívat se do GNU make manual sekce 5.7; je to velmi užitečné.
Do svého kořenového souboru Makefile můžete přidat pravidla, abyste mohli zkompilovat potřebné soubory cpp v jiných adresářích. Níže uvedený příklad Makefile by měl být dobrým začátkem k tomu, abyste se dostali tam, kde chcete být.
CC=g++
TARGET=cppTest
OTHERDIR=../../someotherpath/in/project/src
SOURCE = cppTest.cpp
SOURCE = $(OTHERDIR)/file.cpp
## End sources definition
INCLUDE = -I./ $(AN_INCLUDE_DIR)
INCLUDE = -I.$(OTHERDIR)/../inc
## end more includes
VPATH=$(OTHERDIR)
OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o)))
## Fix dependency destination to be ../.dep relative to the src dir
DEPENDS=$(join $(addsuffix ../.dep/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.d)))
## Default rule executed
all: $(TARGET)
@true
## Clean Rule
clean:
@-rm -f $(TARGET) $(OBJ) $(DEPENDS)
## Rule for making the actual target
$(TARGET): $(OBJ)
@echo "============="
@echo "Linking the target example@unixlinux.online"
@echo "============="
@$(CC) $(CFLAGS) -o example@unixlinux.online $^ $(LIBS)
@echo -- Link finished --
## Generic compilation rule
%.o : %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo "Compiling $<"
@$(CC) $(CFLAGS) -c $< -o example@unixlinux.online
## Rules for object files from cpp files
## Object file for each file is put in obj directory
## one level up from the actual source directory.
../obj/%.o : %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo "Compiling $<"
@$(CC) $(CFLAGS) -c $< -o example@unixlinux.online
# Rule for "other directory" You will need one per "other" dir
$(OTHERDIR)/../obj/%.o : %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo "Compiling $<"
@$(CC) $(CFLAGS) -c $< -o example@unixlinux.online
## Make dependancy rules
../.dep/%.d: %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo Building dependencies file for $*.o
@$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > example@unixlinux.online'
## Dependency rule for "other" directory
$(OTHERDIR)/../.dep/%.d: %.cpp
@mkdir -p $(dir example@unixlinux.online)
@echo "============="
@echo Building dependencies file for $*.o
@$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > example@unixlinux.online'
## Include the dependency files
-include $(DEPENDS)
Mohla by se hodit volba VPATH, která říká make, ve kterých adresářích hledat zdrojový kód. Stále byste však potřebovali volbu -I pro každou cestu začlenění. Příklad:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
To automaticky najde odpovídající soubory partXapi.cpp v libovolném adresáři specifikovaném VPATH a zkompiluje je. To je však užitečnější, když je váš adresář src rozdělen na podadresáře. Pro to, co popisujete, jak již řekli jiní, je pro vás pravděpodobně lepší vytvořit soubor makefile pro každou část, zvláště pokud každá část může stát samostatně.
Pokud máte kód v jednom podadresáři závislý na kódu v jiném podadresáři, pravděpodobně vám bude lépe s jedním makefile na nejvyšší úrovni.
Úplné zdůvodnění naleznete v části Rekurzivní způsob, který je považován za škodlivý, ale v zásadě chcete mít k dispozici úplné informace, které potřebuje k rozhodnutí, zda je třeba soubor znovu sestavit, a nebude to mít, pokud mu řeknete jen asi třetinu váš projekt.
Zdá se, že výše uvedený odkaz není dostupný. Stejný dokument je dostupný zde:
- aegis.sourceforge.net (archivováno)
- lcgapp.cern.ch