Я хотел бы разделить мой список исходных файлов на их собственный файл (source.list), чтобы мне не приходилось обновлять Makefile каждый раз, когда я что-то добавляю.
source.list выглядит так:
a_file.cpp
another_file.cpp
...
xyz_file.cpp
с каждым файлом на новой строке.
Как я могу получить этот список в Makefile как список, разделенный пробелами?
Настроить скрипт bash можно при необходимости. Я знаю, что для этого можно использовать awk, но я бы предпочел избегать его, если это вообще возможно
SOURCE_LIST := $(shell cat source.list)
В gmake использовать $(wildcard *.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, например, когда вы добавляете новый исходный файл, который нужно будет скомпилировать. Что ты Можно do только в отдельном списке переключает реальный исходный файл и / или изменяет зависимости цели, не касаясь Makefile.
Это все хорошо, за исключением того, что это ужасно и не масштабируется. Пожалуйста, используйте генератор системы сборки, такой как CMake, иначе вы не будете веселиться, когда ваш проект развивается.
EDIT2: Добавлена фальшивая цель, от которой ожидают все.
EDIT3: Обратите внимание: приведенное выше предполагает, что вы замените 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 теперь может иметь любое имя, которое вы хотите выбрать, и не PHONY цель. Также обратите внимание, что любой используемый исходный файл также является частью списка зависимостей цели — однако, только исходники передаются на g ++ для компиляции.