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
),但是:
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
。有可能避免这种情况吗?