簡體   English   中英

Makefile:為每個包含的頭自動編譯源代碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM