C++ 将源文件列表放入Makefile的最佳方法

C++ 将源文件列表放入Makefile的最佳方法,c++,file-io,makefile,configure,C++,File Io,Makefile,Configure,我想将我的源文件列表分离到它们自己的文件(source.list)中,这样我就不必每次添加内容时都更新Makefile source.list看起来像: a_file.cpp another_file.cpp ... xyz_file.cpp 每个文件都在换行符上 如何将该列表作为空格分隔的列表放入Makefile中 如果需要,可以使用configure bash脚本。我知道awk可以用于此,但如果可能的话,我宁愿避免使用它。在gmake中使用$(通配符*.cpp) 如果需要,您可以使用对列表

我想将我的源文件列表分离到它们自己的文件(source.list)中,这样我就不必每次添加内容时都更新Makefile

source.list看起来像:

a_file.cpp
another_file.cpp
...
xyz_file.cpp
每个文件都在换行符上

如何将该列表作为空格分隔的列表放入Makefile中

如果需要,可以使用configure bash脚本。我知道awk可以用于此,但如果可能的话,我宁愿避免使用它。

在gmake中使用
$(通配符*.cpp)

如果需要,您可以使用对列表进行操作的其他函数来过滤掉一些源文件。

在gmake中使用
$(通配符*.cpp)


如果需要,您可以使用对列表进行操作的其他函数来过滤掉一些源文件。

如果您确实需要将源文件放入单独的文件中,您只需使用一个或多个变量,具体取决于需要将所有翻译单元编译成目标文件的目标数量:

SOURCE_OBJ1 = src1.cpp depends1 depends2 ...
SOURCE_OBJ2 = src2.cpp depends1 depends2 ...
....
将其保存到sources.list,并将其包含在Makefile中的实际目标定义之前:

include sources.list
 .PHONY: all
 all: executable

 executable: obj1.o obj2.o
    g++ -o executable obj1.o obj2.o

 src1.o: $(SOURCE_OBJ1)
 src2.o: $(SOURCE_OBJ2)
编辑:我将该方法推广到具有一个或多个依赖项(源文件本身除外)的多个目标。在某些时候,您将需要再次访问Makefile本身,例如,当您添加需要编译的新源文件时。仅在单独的列表中,您就可以切换实际的源文件和/或更改目标的依赖项,而无需触摸Makefile

这一切都是好的,除了它是可怕的,不能扩展的事实。请使用像CMake这样的构建系统生成器,否则当您的项目增长时,您将无法获得乐趣

EDIT2:添加了所有人都期待的虚假目标

EDIT3:请注意:以上要求您使用实际的源文件名(如main)替换src1等。否则make将不会导出相应的g++命令行,并且可能会将作为依赖项提到的头文件添加到源文件列表中。结果是一个不可用的对象文件

或者,您可以为源和依赖项指定一个变量,然后指定如何自己调用编译器:

# sources.list
SOURCES_OBJ1 = src1 src2 src3 # only source files here
DEPENDS_OBJ1 = $(SOURCES_OBJ1) dep1 dep2 dep3 # dependencies might include different file types

# ....

# Makefile
# all the other stuff here
obj1.o: $(DEPENDS_OBJ1) # can now be names however you see fit
        g++ -c $(SOURCES_OBJ1) -o obj1.o # handle compiler invocation manually

请注意,obj1.o现在可以有您想要选择的任何名称,并且不是虚假目标。还请注意,所使用的任何源文件也是目标依赖项列表的一部分-但是,只有源文件会传递给g++进行编译。

如果确实需要将源文件放入单独的文件中,只需使用一个或多个变量,根据需要将所有翻译单元编译成目标文件的目标数量:

SOURCE_OBJ1 = src1.cpp depends1 depends2 ...
SOURCE_OBJ2 = src2.cpp depends1 depends2 ...
....
SOURCE_LIST := $(shell cat source.list)
将其保存到sources.list,并将其包含在Makefile中的实际目标定义之前:

include sources.list
 .PHONY: all
 all: executable

 executable: obj1.o obj2.o
    g++ -o executable obj1.o obj2.o

 src1.o: $(SOURCE_OBJ1)
 src2.o: $(SOURCE_OBJ2)
编辑:我将该方法推广到具有一个或多个依赖项(源文件本身除外)的多个目标。在某些时候,您将需要再次访问Makefile本身,例如,当您添加需要编译的新源文件时。仅在单独的列表中,您就可以切换实际的源文件和/或更改目标的依赖项,而无需触摸Makefile

这一切都是好的,除了它是可怕的,不能扩展的事实。请使用像CMake这样的构建系统生成器,否则当您的项目增长时,您将无法获得乐趣

EDIT2:添加了所有人都期待的虚假目标

EDIT3:请注意:以上要求您使用实际的源文件名(如main)替换src1等。否则make将不会导出相应的g++命令行,并且可能会将作为依赖项提到的头文件添加到源文件列表中。结果是一个不可用的对象文件

或者,您可以为源和依赖项指定一个变量,然后指定如何自己调用编译器:

# sources.list
SOURCES_OBJ1 = src1 src2 src3 # only source files here
DEPENDS_OBJ1 = $(SOURCES_OBJ1) dep1 dep2 dep3 # dependencies might include different file types

# ....

# Makefile
# all the other stuff here
obj1.o: $(DEPENDS_OBJ1) # can now be names however you see fit
        g++ -c $(SOURCES_OBJ1) -o obj1.o # handle compiler invocation manually

请注意,obj1.o现在可以有您想要选择的任何名称,并且不是虚假目标。还请注意,使用的任何源文件也是目标依赖项列表的一部分-但是,只有源文件被传递给g++进行编译。

为什么要手工编写Makefile?构建系统生成器是不可能的吗?可以使用配置脚本,但除此之外,什么都不可以。为什么要手工编写Makefile?构建系统生成器是不可能的吗?可以使用配置脚本,但除此之外,没有其他方法可以让您知道要过滤哪些文件名?@Beta:我一般不建议使用globbing来创建源代码列表,但这是需要的(或者至少不必编辑Makefile)。如果可能的话,我不想再添加一个文件$(过滤掉$(排除的源),$(通配符*.cpp))将过滤掉不需要的源。如果要添加大部分源代码,这是一件好事。我们如何知道要过滤掉哪些文件名?@Beta:我一般不建议使用globbing创建源代码列表,但这是需要的(或者至少不必编辑Makefile)。如果可能的话,我不想再添加一个文件$(过滤掉$(排除的源),$(通配符*.cpp))将过滤掉不需要的源。如果要增加大多数来源,这是一件好事。
SOURCE_LIST := $(shell cat source.list)