C++ 如何创建包含子文件夹的通用make文件?

C++ 如何创建包含子文件夹的通用make文件?,c++,makefile,C++,Makefile,当然这个问题已经被问过很多次了,但是我找不到正确的答案,所以我在问 我有以下项目结构: /root | obj | Makefile | src/ | | dir1/ | | | 1.cpp | | dir2/ | | | 2.cpp | | | dir3/ | | | | 3.cpp | | | | 4.cpp | | main.cpp 我是否可以拥有一个通用makefile,用于编译任何子文件夹中的所有cpp文件,该子文件夹具有src文件夹的任何深度和将

当然这个问题已经被问过很多次了,但是我找不到正确的答案,所以我在问

我有以下项目结构:

/root
 | obj
 | Makefile
 | src/
 | | dir1/
 | |  | 1.cpp
 | | dir2/
 | |  | 2.cpp
 | |  | dir3/
 | |  |  | 3.cpp
 | |  |  | 4.cpp
 | | main.cpp
我是否可以拥有一个通用makefile,用于编译任何子文件夹中的所有cpp文件,该子文件夹具有src文件夹的任何深度和将生成对象文件到obj目录中的


注意:这个项目是使用Eclipse CDT开发的,我现在希望能够提供源代码,而不需要用户安装Eclipse来构建它。好吧,我不打算回答这个问题(这个答案本身不是关于
make
),但是:

  • OP表示,他并不是专门针对
    make
    ,而是最简单的解决方案

  • 目前还没有明确的答案

  • 下面是如何在
    cmake
    SCons
    中执行此操作<请注意< <强> >我的目的不是贬低<代码>使<代码>,提倡以下两个(我必须说的是,我现在被认为是当今主流的C++构建系统)等。 CMake

    在CMake中,您可以使用如下内容:

    file(GLOB_RECURSE variable [RELATIVE path] 
    [FOLLOW_SYMLINKS] [globbing expressions]...)
    
    def getSubdirs(abs_path_dir):  
        lst = [ name for name in os.listdir(abs_path_dir) if os.path.isdir(os.path.join(abs_path_dir, name)) and name[0] != '.' ]    
        lst.sort()
        return lst
    
    (有关更多信息,请参阅。)

    Scons

    在SCON中,您可以使用以下内容:

    file(GLOB_RECURSE variable [RELATIVE path] 
    [FOLLOW_SYMLINKS] [globbing expressions]...)
    
    def getSubdirs(abs_path_dir):  
        lst = [ name for name in os.listdir(abs_path_dir) if os.path.isdir(os.path.join(abs_path_dir, name)) and name[0] != '.' ]    
        lst.sort()
        return lst
    

    (有关更多信息,请参阅。)

    要实现“无限”递归,可以将通配符与扩展模式一起使用:

    CPPFILES := $(wildcard src/**/*.cpp)
    
    然后,您可以将它们转换为
    .o
    文件列表:

    OBJFILES := $(patsubst src/%.cpp,obj/%.o,$(CPPFILES))
    
    现在我们有了构建目标:

    .PHONY: all
    all: $(OBJFILES)
    
    汇编规则:

    obj/%.o: src/%.cpp
        mkdir -p "$(@D)"
        $(CC) -c $< -o $@
    

    哇,2016年开始使用make!:-)@AmiTavory我只是在寻找一个最简单的解决方案来解决这个问题,make或anothermake并不是专门为此设计的。您可能需要编写一个脚本来动态构建Makefile。或者切换到另一个构建系统,比如scons。@AmiTavory,嗯?make怎么了?CMake只是一个make文件生成器,所以它仍然使用make。我个人在configure+make方面的经验比cmake要好得多。@SergeyA我真的没有和你争论过。我想这与我们必须进行的特定类型的构建的特殊性有关。我的猜测是,就像其他大量使用的工具一样,一种工具对某些人来说更适合某些任务,而另一种工具对某些人来说更适合其他任务。:-)可能值得一提的是,正如链接的SO问题中提到的,CMake缓存找到的文件,因此如果添加、删除或重命名文件,则需要删除并重新生成CMake文件。我没有使用SCON,所以我不知道它是否有相同的行为。OP不清楚他们是想在
    obj
    中使用镜像目录,还是只需要一个
    obj
    目录,所以这可能不是真正需要的,但做得很好(对于单个
    obj
    dir很容易修复)。如果您碰巧有两个同名的文件,只是在不同的目录中,那么在这种情况下,一个obj目录将中断。另请参阅我对make internal recursive通配符函数的回答(以及我在其上找到的源链接).我完全同意,但人们似乎还是照例要求它。它运行得非常好,只是执行了多次
    mkdir-p
    。有可能避免这种情况吗?