重新编译仅更改的文件(两步)

问题描述:

我已经阅读了几个关于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文件时,它什么也没做。

你能帮我发现错误吗?

+0

您的变量“PPX_FILES”和“CPP_FILES”具有误导性,因为“PPX_FILES”列出了C++源文件,“CPP_FILES”列出了目标文件。您也不需要从磁盘中为每个变量获取文件名,只需替换第一个变量的后缀即可。 –

+0

您的ppx工具是否会重新生成尚未更改的文件?他们的时间戳是否改变? –

+0

@RetiredNinja是的,它的确如此。我试图用'make'来避免这种情况。 – senseiwa

第1步:构建foo.cppfoo.hfoo.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.ofoo.cppfoo.h(和bar.hbaz.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问题(我不必实验),它仍然出现故障,然后让我们知道一条评论;我很确定修复很简单。

+0

感谢您的回答,它效果很好。我只有一个问题:为什么'make'删除生成的'cpp'文件?我没有想到。这对我来说很酷,因为在创建库之后我不需要它们,但是是否可以删除'.h'文件? (我已经将它们复制到另一个目录中) – senseiwa

+1

@senseiwa:认为'cpp'文件[*中间文件*](https://www.gnu.org/software/make/manual/make.html#Chained -Rules),并在工作完成后将其删除。删除头文件('.h')的最简单方法是在'$(LIB)'规则中添加'rm -f $(TARGET_TEMP_DIR)/ *。h'命令。 Make可以将它们视为中间文件,但它很复杂。 – Beta