使用子目录制作和重新编译标题

时间:2014-05-16 16:17:05

标签: c++ makefile

有一些与我尝试做的事情有关的不同问题,例如thisthisthis。但是,我已经看过那里有什么以及它们链接到什么,我仍然无法让它工作。

我有以下make文件(我对此here有一些帮助)。它在源目录中的.cpps的构建目录中构建.os。我想调整这个,以便如果标题更新,那么它正确地重新编译那些,所以我不必make clean整个事情(最特别是INC_DIR1文件夹中的那些)。

CC = g++
CFLAGS = -g -Wall

INC_DIR1 = include
INC_DIR2 = C:/CPPFiles/CPP_Extra_Libraries/armadillo-4.200.0/include
INC_DIR = $(INC_DIR1) $(INC_DIR2)
INCLUDES = $(foreach d, $(INC_DIR), -I$d)

BUILD_DIR = build
SRC_DIR = test

SRC = $(wildcard */*.cpp)

VPATH = $(SRC_DIR)

OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(SRC:.cpp=.o)))

MAIN = armadillo_extra_functions_test

.PHONY: depend clean

all: $(BUILD_DIR) $(MAIN)
    @echo  compilation complete

$(BUILD_DIR):
    mkdir -p $@

$(BUILD_DIR)/%.o: %.cpp
    $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(MAIN): $(OBJS) 
    $(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS)

clean:
    $(RM) *.o *~ $(MAIN) $(BUILD_DIR)/*.o

depend: $(SRC)
    makedepend $(INCLUDES) $^

我尝试过的最新事情是删除dependmakedepend语句,然后用

替换$(BUILD_DIR/%.o: %.cpp语句
DEPS = $(patsubst %.o, %.d, $(OBJS))

-include $(DEPS)

$(BUILD_DIR)/%.o: %.cpp
    $(CC) -c $(CFLAGS) $(INCLUDES) $< -o $@
    $(CC) -c $(CFLAGS) -MMD  $< > $(DEPS)

如果没有这些调整的最后一行,make文件会运行,但不会更新标头。但是,当我在最后一行添加时,我收到有关$(BUILD_DIR)/%.d文件不存在的错误。

2 个答案:

答案 0 :(得分:2)

基本上你需要构造makefile,以便.cpp文件依赖于头文件。这样,对标头的更改将触发重新编译.cpp文件。为了使这更容易,理想情况下,每个.cpp文件的头依赖关系将自动确定。

我建议使用GNU autotools方法(非常适合您将以源代码形式发布的软件),jam(非常简单的配置)或(我当前最喜欢的)CMake。所有这些基本上都是从另一个文件(或一组文件)自动生成makefile。它们也自动处理依赖项检测和管理。我只会手工制作一个makefile来进行自我教育,或者仅仅提供一些源文件,或者可能是一些奇怪而复杂的东西。

答案 1 :(得分:1)

你的-MMD标志几乎是正确的,但没有必要使事情复杂化:

INC_DIR1    :=  include
INC_DIR2    :=  C:/CPPFiles/CPP_Extra_Libraries/armadillo-4.200.0/include
INC_DIRS    :=  $(INC_DIR1) $(INC_DIR2)

BUILD_DIR   :=  build
SRC_DIR     :=  test

SRCS        :=  $(wildcard $(SRC_DIR)/*.cpp)
OBJS        :=  $(SRCS:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
DEPS        :=  $(OBJS:.o=.d)

LDLIBS      :=  # -l flags
LDFLAGS     :=  # -L flags

CPPFLAGS    :=  -MMD -MP $(foreach DIR, $(INC_DIRS), -I $(DIR))
CXXFLAGS    :=  -W -Wall

MAIN        :=  armadillo_extra_functions_test

.PHONY: all clean

all:    $(MAIN)
    @echo "compilation complete"

$(MAIN):    $(OBJS)
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

clean:
    $(RM) -r $(MAIN) $(BUILD_DIR)

-include $(DEPS)

$(BUILD_DIR):
    mkdir $@

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp | $(BUILD_DIR)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<

一些快速说明:

  • 您正在使用C ++。删除C ++版本的$(CC)$(CFLAGS) C变量:$(CXX)$(CXXFLAGS)变量。

  • $(CPPFLAGS)适用于预处理程序标记,例如-MMD-MP-I

  • 您需要在依赖项文件中包含GCC规则。