C++ 如何将源目录到对象的所有cpp文件编译到单独的生成目录中

C++ 如何将源目录到对象的所有cpp文件编译到单独的生成目录中,c++,build,makefile,C++,Build,Makefile,我的问题是这个问题的延伸 我的项目具有类似的结构,但我的根/项目目录之外有远远不止一个src文件夹,包括文件夹: /somedir /project Makefile main /src1 main.cpp foo.cpp foo.h /src2 bar.cpp bar.h ... /srcn baz.cpp baz.cpp /obj mai

我的问题是这个问题的延伸

我的项目具有类似的结构,但我的根/项目目录之外有远远不止一个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 $@))
SOURCES=${wildcard src1/*.cpp}
SOURCES+=${通配符src2/*.cpp}
...
SOURCES+=../ext\u srcn/zetta.cpp
对象=$(源:.cpp=.o)
main:$(对象)
$(CC)$(LD_标志)-o$@$^
.cpp.o:
$(CC)$(CFLAGS)-c$<$(包括)-o$(addprefix obj/,$(notdir$@))

但是现在,当然,我所有的源代码每次都会重新编译,即使没有做任何更改。那太可怕了。如何在obj上追踪.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 $@

和,通常-依赖关系会很好。

这不是C++,我不认为<>代码> CPP < /Cuff>使用标签:/@ @ SypLogiT果糖,它具体与 C++ +/Cuth>编译,所以标签在这里是可以的。你可以尝试设置并指定你的目标<代码> o < /C> >所需的构建路径。(在确保这个存在的同时!)也为您的对象文件生成并包含这些文件。我采用了另一种技术,基于πάντα建议的VPATHῥεῖ. 但您的建议似乎更一般,因为它允许在不同的文件夹中使用相同名称的.cpp文件。这就是我将您的答案标记为已接受的原因。
/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