[英]Does compiler compiles all included header files along with the main program every time we compile that program?
[英]Makefile: automatically compile source for every included header
如果目標包含#include "foo/bar.hpp"
,我是否可以自動編譯並鏈接foo/bar.cpp
配置我的makefile?
詳細信息:我有一個類似於以下項目的makefile:
src/
|-- program1/
| |-- main.cpp
| |-- makefile
|-- modules/
| |-- module1/
| | |-- foo.cpp
| | |-- foo.hpp
| |-- module1/
| | |-- bar.cpp
| | |-- bar.hpp
目前我的program1的makefile包含了它所使用的所有模塊的所有* .cpp文件的列表,這種文件很難維護並且容易與我的包含保持同步。
但是,在我的代碼中,遵循#include
命令將提供精確的依賴樹。 對於每個* .hpp,都需要編譯和鏈接相應的* .cpp。
這個編譯過程可以通過makefile自動化嗎? 願自動依賴可以幫助我嗎?
有問題的makefile:
# compiler settings
CXX = g++
CXXFLAGS = -std=c++14
# object file generation path
tmpDir = .objs
# modules path
modPath = ../modules
# Names of modules and files to be compiled
names := \
main.o \
module1/foo.o \
module2/bar.o
# prepend tmpDir
names := $(addprefix $(tmpDir)/, $(names))
# Linking
main: $(names)
$(CXX) $(CXXFLAGS) -o main $^
# Rule for main file
$(tmpDir)/main.o: main.cpp
@mkdir -p $(tmpDir)
$(CXX) $(CXXFLAGS) -c main.cpp -o $@ -I "$(modPath)"
# rules for module files
$(tmpDir)/%.o: $(modPath)/%.cpp
mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -rf *.o main $(tmpDir)
我想避免手動設置names
。
自動生成文件名的常用方法是使用$(wildcard ...)
或某些$(shell ...)
命令來掃描目錄。
基於您鏈接的Makefile
,我認為您可以使用GCC
跟蹤依賴關系-MMD -MP
標志,如下所示:
# compiler settings
CXX = g++
# use flags to generate dependency files
CXXFLAGS = -std=c++14 -MMD -MP
# object file generation path
tmpDir = .objs
# modules path
modPath = ../modules
# Names of modules and files to be compiled
names := main.o
names += $(patsubst $(modPath)/%.cpp,%.o,$(shell find $(modPath) -iname "*.cpp"))
# prepend tmpDir
names := $(addprefix $(tmpDir)/, $(names))
# there should be a dep file for every object file
deps := $(patsubst %.o,%.d,$(names))
all: main
# Linking
main: $(names)
$(CXX) $(CXXFLAGS) -o main $^
# Rule for main file
$(tmpDir)/main.o: main.cpp
@mkdir -p $(tmpDir)
$(CXX) $(CXXFLAGS) -c main.cpp -o $@ -I "$(modPath)"
# rules for module files
$(tmpDir)/%.o: $(modPath)/%.cpp
mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -c $< -o $@
# include the dependencies if they exist
-include $(deps)
clean:
rm -rf *.o main $(tmpDir) $(deps)
每個使用-MMD -MP
標志的編譯命令都將生成與輸出文件對應的依賴文件(擴展名為.d
除外)。
關於:*目前我的program1的makefile包含它使用的所有模塊的所有* .cpp文件的列表,這有點難以維護並且容易與我的包含同步。
但是,在我的代碼中,遵循#include命令將提供精確的依賴樹。 對於每個* .hpp,都需要編譯和鏈接相應的* .cpp。
這個編譯過程可以通過makefile自動化嗎? 願自動依賴可以幫助我嗎?*
在makefile中,您可以使用對find
命令的調用輸出來獲取modules
目錄下面目錄中所有(例如)* .cpp文件的列表,而不是硬編碼列表。
我稍微改進了Galik的答案。 現在它的行為與我正在尋找的非常相似。
我不是手動定義names
,而是調用文件搜索。 然后,結果將過濾以僅匹配具有相同名稱的* .hpp文件的* .cpp文件。 這會忽略包含測試的所有文件:
# find *.hpp files
names := $(shell find $(modPath) -iname "*.hpp")
# replace extension .hpp -> .cpp
names := $(patsubst %,%.cpp,$(basename $(names)))
# filter nonexistent *.cpp files
names := $(wildcard $(names))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.