重新编译仅更改的文件(两步)
我已经阅读了几个关于SO的问题,但我的Makefile
仍然无法达到我想要的效果。与其他问题相反,我在这里有一个两步编译。步骤如下这些:重新编译仅更改的文件(两步)
- 使用预处理工具(称为
ppx
)产生.cpp
和.h
文件, - 然后编译他们产生
.o
文件, - 最终创建一个动态库。
所有这些都在Xcode环境(自定义构建目标)内,因此您可以看到所有那些$(TARGET_TEMP_DIR)
和类似的变量。
的make
命令调用其中ppx
文件,但我需要放置在正确的目录中的所有生成的文件(.cpp
,.h
,.o
和.dylib
)(见$(LIB)
)。
注意:ppx
工具不保留时间戳。
这是我的失败尝试:
# target and compiler
LIB=$(TARGET_TEMP_DIR)/$(TARGET_NAME).dylib
PPX=$(HOME)/bin/ppx
# c++ compiler
CXXFLAGS=-std=c++14
# files
PPX_FILES := $(patsubst %.ppx, %.cpp, $(wildcard *.ppx))
CPP_FILES := $(patsubst %.ppx, %.o, $(wildcard *.ppx))
OBJ_FILES := $(addprefix $(TARGET_TEMP_DIR)/,$(CPP_FILES:%.cpp=%.o))
# link library
all: $(LIB)
$(LIB): $(PPX_FILES) $(CPP_FILES) $(OBJ_FILES)
$(CXX) -dynamiclib -o $(LIB) $(OBJ_FILES)
# preprocess, generating source and header
%.cpp: %.ppx
$(PPX) -o $(TARGET_TEMP_DIR) $<
# compile cpp source files
%.o: %.cpp
$(CXX) $(CXXFLAGS) -Ofast -o $(TARGET_TEMP_DIR)/[email protected] -c $(TARGET_TEMP_DIR)/$<
以上Makefile
总是重新编译所有文件。在阅读了我在这里找到的所有问题之后,我成功做的唯一一件事是从不重新编译Makefile
,所以当我更改ppx
文件时,它什么也没做。
你能帮我发现错误吗?
第1步:构建foo.cpp
和foo.h
从foo.ppx
,并把它们在正确的目录。 (我明白你的意思是说, “正确的目录” 是$(TARGET_TEMP_DIR)
,但你是一个有点神秘。)
# preprocess, generating source and header
$(TARGET_TEMP_DIR)/%.cpp: %.ppx
$(PPX) -o $(TARGET_TEMP_DIR) $<
或更好:
# preprocess, generating source and header
$(TARGET_TEMP_DIR)/%.cpp: %.ppx
$(PPX) -o $(dir [email protected]) $<
第2步:构建foo.o
从foo.cpp
和foo.h
(和bar.h
和baz.h
,如果需要的话,我建议你接下来看看自动的依赖关系处理。)
# compile cpp source files
%.o: %.cpp
$(CXX) $(CXXFLAGS) -Ofast -o [email protected] -c $<
第3步:建设所需的目标文件的列表,用理性的名字:
# files
PPX_FILES := $(wildcard *.ppx)
OBJ_FILES := $(patsubst %.ppx, $(TARGET_TEMP_DIR)/%.o, $(PPX_FILES))
第4步:构建库:
$(LIB): $(OBJ_FILES)
$(CXX) -dynamiclib -o [email protected] $^
如果由于时间戳和ppx问题(我不必实验),它仍然出现故障,然后让我们知道一条评论;我很确定修复很简单。
感谢您的回答,它效果很好。我只有一个问题:为什么'make'删除生成的'cpp'文件?我没有想到。这对我来说很酷,因为在创建库之后我不需要它们,但是是否可以删除'.h'文件? (我已经将它们复制到另一个目录中) – senseiwa
@senseiwa:认为'cpp'文件[*中间文件*](https://www.gnu.org/software/make/manual/make.html#Chained -Rules),并在工作完成后将其删除。删除头文件('.h')的最简单方法是在'$(LIB)'规则中添加'rm -f $(TARGET_TEMP_DIR)/ *。h'命令。 Make可以将它们视为中间文件,但它很复杂。 – Beta
您的变量“PPX_FILES”和“CPP_FILES”具有误导性,因为“PPX_FILES”列出了C++源文件,“CPP_FILES”列出了目标文件。您也不需要从磁盘中为每个变量获取文件名,只需替换第一个变量的后缀即可。 –
您的ppx工具是否会重新生成尚未更改的文件?他们的时间戳是否改变? –
@RetiredNinja是的,它的确如此。我试图用'make'来避免这种情况。 – senseiwa