【问题标题】:C/C++ Makefile: How to build dependencies between with .c files and object files in other directories?C/C++ Makefile:如何在 .c 文件和其他目录中的目标文件之间建立依赖关系?
【发布时间】:2014-10-02 09:56:27
【问题描述】:

这是我的 .c 和 .o 文件层次结构:

---/src/IRBuild/main.c
                func1.c
                func2.c
---/inclue/main.h
           func1.h
           func2.h

---/build/IRBuild/main.o
                  func1.o
                  func2.o 
                  irbuild

下面是我在 ~/src/IRBuild/ 下的 Makefile,我使用 .c 和 .h 文件构建了编译依赖项,这意味着每当 .c 或 .h 文件发生更改时。 “make”将重建目标文件。但是因为我将 .o 文件输出到 ~/build/IRBuild/,而不是当前目录,所以“make”将在我每次 make 时重建所有 .o 文件。

我应该如何使用其他目录中的 .o 文件构建依赖关系?仅在特定文件的 .c、.h 或 .o 文件更改时重新编译?

在这里呆了两天,非常感谢!

   EXE=irbuild

# G++ as default compiler
CC=g++

# Compile time flags
CXXFLAGS = -g -Wall

# Library paths in addition to /usr/lib
LFLAGS=-std=c++0x

# Libraries to link into executable:
#LIBS = -lmylib -lm

# Include files directory other than /usr/include
INCLUDES=-I../../include/

SRC=$(wildcard *.cpp)
OBJ=$(SRC:.cpp=.o)
DEP=$(OBJ:.o=.d)
BUILD=../../build/IRBuild
TESTS=../../tests/

OBJS :=$(foreach obj, $(OBJ), $(BUILD)/$(obj))

.PHONY: depend clean

all: $(EXE)
        cp $(EXE) $(TESTS)
$(EXE): $(OBJ)
        $(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -o $(EXE) $(OBJS)

.cpp.o:
        $(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -c $< -o $(BUILD)/$@

clean:
        rm -f $(OBJS) $(DEP) $(EXE)

depend: .depend
.depend: $(SRC)
        rm -f ./.depend
        $(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -MM $^ -MF ./.depend;
include .depend
   

【问题讨论】:

    标签: c++ object makefile dependencies


    【解决方案1】:

    你违反了http://make.mad-scientist.net/rules.html 的规则 2,这就是为什么它总是在它认为它们不存在的时候重建它们。 (在 prereqs 中列出 $(OBJ) 和在配方链接行中列出 $(OBJS) 也有点像 makefile 的“气味”。)

    您需要使用将目标文件正确映射到其先决条件的规则。

    手动或使用vpath

    有多种方法可以使手动方法发挥作用,具体取决于您要投入多少精力来进行设置。 vpath 方法可能会更简单一些。

    使用vpath 应该只需要使用$(OBJS) 作为$(EXE) 先决条件,然后添加vpath %.cpp .vpath %.h ../../include 或类似的东西。

    【讨论】:

    • 谢谢Etan,你的意思是这条规则违反了规则2吗? code .cpp.o: $(CC) $(CXXFLAGS) $(LFLAGS) $(INCLUDES) -c $code 怎么改??如果我删除 $(BUILD),$@ 只会生成目标文件本身,其中没有路径信息。 vpath 正在处理先决条件,对吗?但我说的是依赖关系,我怎样才能用其他目录中的 .o 文件构建依赖关系?
    • 是的,那个食谱行。您的食谱需要完全 $@ 生成,而不是它的变体。正确,vpath 用于先决条件。这就是为什么当我提到我说你使用$(OBJS) 作为先决条件时,因为文件名中有$(BUILD) 路径,然后你让vpath 找到这些目标文件的匹配源。
    • Etan,它有效!我添加“vpath %.o ../../build/IRBuild”,然后就可以了!谢谢!我没有 15 个声望,所以我不能投票给你。
    • 如果您在该后缀规则中从 $@ 中删除 $(BUILD) 并添加 vpath 指令,我想它可能会起作用。我不会那样做,但如果它有效,它就有效。即使您不能投票,您也应该能够接受答案。
    猜你喜欢
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    相关资源
    最近更新 更多