make clean 后需要运行 make 两次

Need to run make twice after make clean

我想做的就是将来自不同源目录的源文件收集到一个文件夹中,然后构建这些 make 文件。在 make clean 之后,我必须 运行 make 命令两次才能进行构建。

所以我先 运行 make clean,然后我 运行 make,这会抛出一个错误,说找不到 -o 文件。但是当 iI运行 再次 make 时,构建会通过并生成构建文件。

我的 makefile 如下所示

.PHONY:  dirs all clean

all: dirs $(OBJ_DIR) $(OBJ_FILES) 
    "$(CC) -rvn fLib.a $(OBJ_FILES)

# clean build target. Remove all files without reporting errors in case they don't exist.
clean:
    @rm -rf fLib.a $(OBJ_DIR)

# Build target for creating flat header file folder for SharedTrackerAPI (FLAT_INC_DIR) 
# due to too long paths in Windows 7 build
dirs:
    @echo 'Making flat source and header folders.'
    @mkdir -p $(OBJ_DIR)
    @for f in $(SRC_FILES); do cp $$f $(OBJ_DIR); done
    @mkdir -p $(FLAT_INC_DIR) 
    @OLD_CWD=$(CURDIR)
    @cd $(FLAT_INC_DIR)
    @find  $(STA_RADAR_TRACKER_IFACE) -name '*.h' | xargs -i  cp -l {} $(FLAT_INC_DIR)
    @cd $(OLD_CWD)

$(OBJ_DIR)/%.o: $(OBJ_DIR)/%.cpp
    "$(TASKING_CTC_BIN)"/cctc.exe $(CXXFLAGS) -c -o $@ $< $(CC_INCLUDE_PATH) 

我做错了什么,我必须在 make clean 后 运行 make 两次。

问题是虽然 dirs 会将源文件放在平面源目录中,但 Make 不知道。 在执行 dirs 规则,它已经确定它不知道如何构建目标文件。

快速而肮脏的解决方案是告诉 Make "trust me, it'll be fine"; 一种方法是像这样修改对象规则:

$(OBJ_DIR)/%.o:
    "$(TASKING_CTC_BIN)"/cctc.exe $(CXXFLAGS) -c -o $@ $(OBJ_DIR)/$*.cpp $(CC_INCLUDE_PATH)

如果你就此打住,你就会有一个可行的解决方案。

如果您想要一个更干净、高效和灵活的 makefile,您必须重新考虑查找源文件的方法。我认为没有充分的理由使用平面源文件方法,但如果你真的想使用它,这里有一个好方法:

vpath %.cpp $(dir $(SRC_FILES))

$(OBJ_DIR)/%.cpp: %.cpp
    @cp $< $@

现在您可以摆脱 dir 并使用您未修改的对象规则:

$(OBJ_DIR)/%.o: $(OBJ_DIR)/%.cpp
    "$(TASKING_CTC_BIN)"/cctc.exe $(CXXFLAGS) -c -o $@ $< $(CC_INCLUDE_PATH) 

如何处理头文件(FLAT_INC_DIR)由您决定,但我再次推荐vpath