如何将从源目录到对象的所有cpp文件编译到单独的构建目录

How to compile all cpp files from source directories to object into a separate build directory

本文关键字:cpp 文件 构建 单独 编译 对象      更新时间:2023-10-16

我的问题是问题的扩展,我可以编译src/中的所有.cpp文件到obj/中的.o's,然后链接到。/中的二进制文件吗?

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

/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 $@))

但是现在,当然,所有的源代码每次都要重新编译,即使没有做任何更改。这太可怕了。我如何在对象j上追踪我的。o目标的起源?或者可能有其他方法来解决我的任务?

可以将源路径保留在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

并且,- 通常 -依赖项会工作得很好。