【问题标题】:How to compile all cpp files from source directories to object into a separate build directory如何将源目录中的所有 cpp 文件编译为对象到单独的构建目录中
【发布时间】:2014-07-24 04:25:04
【问题描述】:

我的问题是问题Can I compile all .cpp files in src/ to .o's in obj/, then link to binary in ./?的延伸

我的项目具有类似的结构,但我的 src 文件夹不止一个,包括位于我的根 /project 目录之外的文件夹:

/somedir
  /project
    Makefile
    main
    /src1
      main.cpp
      foo.cpp
      foo.h
    /src2
      bar.cpp
      bar.h
    ...
    /srcn
      baz.cpp
      baz.cpp
    /obj
      main.o
      foo.o
      bar.o
      ...
      baz.o
      alpha.o
      betta.o
      ...
      zetta.o
  /ext_src1
    alpha.cpp
  /ext_src2
    betta.cpp
  ...
  /ext_srcn
    zetta.cpp

在我的 Makefile 中,我列出了我需要的所有 cpp,部分是手动收集的,部分是在通配符的帮助下收集的。我假设所有 cpp 文件的名称都不同(并且它们的对象可以安全地放入一个目录中)。现在,如何将它们全部编译到我的 obj 文件夹中?

我几乎通过以下方式做了我想做的事:

SOURCES=${wildcard src1/*.cpp} 
SOURCES+=${wildcard src2/*.cpp} 
...
SOURCES+=../ext_srcn/zetta.cpp 

OBJECTS=$(SOURCES:.cpp=.o)

main: $(OBJECTS)
    $(CC) $(LD_FLAGS) -o $@ $^

.cpp.o:
    $(CC) $(CFLAGS) -c $< $(INCLUDES) -o $(addprefix obj/,$(notdir $@))

但是现在,当然,我所有的源代码每次都会重新编译,即使没有进行任何更改。太糟糕了。如何在 obj 上追踪 .o 目标的来源?或者可能有另一种方法来解决我的任务?

【问题讨论】:

  • 这几乎不是 c++,我不认为.cpp 构成使用标签:/
  • @SyntacticFructose 具体跟C++编译有关,所以这里的tag就可以了。
  • 您可以尝试设置VPATH 并使用所需的构建路径指定您的目标.o(同时确保此路径存在!)。还为您的目标文件生成dependency files 并包含这些。

标签: c++ build makefile


【解决方案1】:

您可以将源路径保留在obj目录中:

TOP := $(realpath ../)
SOURCES := $(wildcard $(TOP)/project/src1/*.cpp)
SOURCES += $(wildcard $(TOP)/project/src2/*.cpp)
...
SOURCES += $(TOP)/ext_srcn/zetta.cpp 

OBJECTS := $(addprefix $(TOP)/project/obj,$(patsubst $(TOP),,$(SOURCES:%.cpp=%.o)))

main: $(OBJECTS)
    $(CC) $(LD_FLAGS) -o $@ $^

$(OBJECTS): $(TOP)/project/obj/%.o: $(TOP)/%.cpp
    $(CC) $(CFLAGS) -c $< $(INCLUDES) -o $@

这样你就会有这样的东西:

/somedir
  /project
    Makefile
    main.cpp
    /src1
      foo.cpp
      foo.h
    /src2
      bar.cpp
      bar.h
    ...
    /srcn
      baz.cpp
      baz.h
    /obj
      /project
        main.o
        /src1
          foo.o
        /src2
          baz.o
        ...
        /srcn
          baz.o
      /ext_src1
        alpha.o
      /ext_src2
        beta.o
      ...
      /ext_srcn
        zetta.o
  /ext_src1
    alpha.cpp
  /ext_src2
    betta.cpp
  ...
  /ext_srcn
    zetta.cpp

而且, - 通常 - 依赖关系会很好地工作。

【讨论】:

  • 我采用了另一种技术,基于 πάντα ῥεῖ 建议的 VPATH。但是您的建议似乎更笼统,因为它允许在不同文件夹中具有相同名称的 .cpp 文件。这就是我将您的答案标记为已接受的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
相关资源
最近更新 更多