2016-12-14 146 views
0

是否有簡單的方法將單個配方應用於多個模式規則?Makefile多個模式的單個配方

考慮這個目錄結構

|- src 
| - file1.cpp 
|- test 
| - file2.cpp 
| - file3.cpp 
| - metrics 
| - file4.cpp 
| - file5.cpp 

我想編寫一個模式規則來編譯test目錄下的所有.cpp文件。這裏是我現在有:

$(OBJS)/%.o: test/%.cpp 
    @mkdir -p $(OBJS) 
    g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 

$(OBJS)/%.o: test/metrics/%.cpp 
    @mkdir -p $(OBJS) 
    g++ $(FLAGS) $(CPPFLAGS) -I test -c $< -o [email protected] 

TEST_CPP := $(wildcard test/*.cpp) $(wildcard test/**/*.cpp) 
TEST_OBJ := $(addprefix $(OBJS)/,$(notdir $(TEST_CPP:.cpp=.o))) 

$(BIN)/testRunner: $(TEST_OBJ) 
    @mkdir -p $(BIN) 
    g++ $(FLAGS) $(CPPFLAGS) $^ $(LIBS) -o [email protected] 

我想避免重複的目標文件的食譜。我想象中的解決方案將是這個樣子:

$(OBJS)/%.o: test/%.cpp 
$(OBJS)/%.o: test/metrics/%.cpp 
    @mkdir -p $(OBJS) 
    g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 

(目前,該OBJ文件目錄是平的,但是,我沒有問題,複製源目錄結構,如果他們簡化了生成文件。)

回答

3

沒有辦法做到你想要的。你可以得到的最接近的是把配方到一個變量,並使用相同的變量每個配方,像這樣:

define BUILD_O 
     @mkdir -p $(OBJS) 
     g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 
endef 

$(OBJS)/%.o : test/%.cpp 
     $(BUILD_O) 
$(OBJS)/%.o : test/metrics/%.cpp 
     $(BUILD_O) 

作爲替代,因爲你希望所有的對象去到同一個目錄但在不同的目錄找貨源,你可以使用VPATH而不是寫只是一個單一的模式規則,就像這樣:

VPATH = test test/metrics 

$(OBJS)/%.o : %.cpp 
     @mkdir -p $(@D) 
     g++ $(FLAGS) $(CPPFLAGS) -c $< -o [email protected] 

我強烈建議你返工你的makefile文件使用標準的變量名,雖然,使用$(CXX),不g++,對於C++編譯器的名稱和$(CXXFLAGS),不$(FLAGS),對於C++編譯器選項。

編輯

如果您需要自定義標記,然後以正常的方式來做到這一點無論是通過target-specific variables,或通過constructed macro names

目標特定的變量應該是這樣的:

test: $(test_targets) 
test: FLAGS += -Dtest 

production: $(production_targets) 
production: FLAGS += -Dproduction 

那麼當您運行make test你會得到-Dtest增加;當你運行make production時,你會得到-Dproduction。這裏有一些問題:如果你運行make myfoo.o那麼你不會得到這些(見文檔)。

構建宏名應該是這樣的:

test_FLAGS = -Dtest 
production_FLAGS = -Dproduction 

rootdir = $(firstword $(subst /, ,$1)) 

VPATH = test test/metrics production production/widgets 

$(OBJS)/%.o : %.cpp 
     @mkdir -p $(@D) 
     g++ $(FLAGS) $(CPPFLAGS) $($(call rootdir,$(<D))_FLAGS) -c $< -o [email protected] 
+0

是否有適用VPATH只有一定的規則的方法嗎?假設我想爲「test」.o文件使用不同的標誌/庫/包含,而不是「產品」.o文件。我可以爲'$(OBJS)/ test /%。o'和'$(OBJS)/ production /%。o'設置不同的模式規則。但是,有沒有辦法將'$(OBJS)/ test'中的.o文件的模式匹配限制爲'/ test'中的源文件? – Zack

+0

'VPATH'是全局的,但你可以使用'vpath $(OBJS)/ test /%。o test'這樣的'vpath'指令(同樣也適用於生產)。 –

+0

你不能像這樣使用'vpath':'vpath'中的模式適用於你正在尋找的名字列表,而不是目標列表。換句話說,你的例子告訴make應該在'test'中查找.o文件,而不是'.cpp'文件。 – MadScientist