Обычно мы сравнительно редко пишем makefile, а вся вроде бы освоенная "магия" так и норовит за полгода улетучиться из головы. Поэтому я стараюсь писать простые Makefile, вроде такого (для вашего случая).
# Эти обозначения я вечно забываю:
# $@ target
# $^ all right part
# $? only new in right part
# $< first name from right part
#
#CC = gcc
#CFLAGS = -g -std=gnu99
CC = g++
CXXFLAGS = -O3 -pthread
SRCS = SubClass.cpp SuperClass.cpp main.cpp
PROGS = programm
all: $(PROGS)
programm: main.o SubClass.o SuperClass.o
$(CC) -o $@ $^ -pthread
.PHONY: clean
clean:
rm -rf $(PROGS) *.o *~ *.bak a.out
depend:
@makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null
# DO NOT DELETE
SubClass.o: f.h data.h
main.o: f.h
Строки после depend с зависимостями .o от .h добавляет команда makedepend (символ @ перед ней подавляет ее вывод в stdout), которая исполняется, когда мы запускаем
> make depend
после изменения состава файлов проекта или добавления наших (не системных) .h файлов в какой-нибудь .cpp
Когда мы вызываем
make
без аргументов, то Makefile начинает выполняться с первой метки (остальные, если не зависят от нее, уже не будут рассматриваться). Здесь all: вроде бы излишня (можно было бы сразу начать файл с programm:), но иногда хочется одним вызовом make собрать сразу несколько модулей и тогда они просто перечисляются в переменной PROGS.
Здесь я в main.cpp включаю f.h, в SubClass.cpp включаю f.h и data.h, а в SuperClass.cpp ничего не включаю.
Make по умолчанию строит зависимости .o от .cpp (или .c) и вызывает g++ с подстановкой значения из переменной CXXFLAGS (а для gcc использует CFLAGS).
Ключи для линкера (вызов $(CC) -o ...) я предпочитаю прописывать явно либо в команде, либо в переменных makefile, которые туда подставляю. Это может сберечь кучу времени при отладке через год-другой (особенно если при вызове make образуется длиннющая "простыня").
Если для компиляции какого-либо файла требуются нестандартные действия, то это прописываем вручную. Например, мы хотим (может быть иногда) использовать при компиляции файла SubClass.cpp переменную препроцессора TEST. Тогда напишем
SubClass.o: SubClass.cpp Makefile
$(CC) $(CXXFLAGS) -c -DTEST $<
где нибудь между all: и depend:. В таком случае мы должны включать в аргументы выполняемой команды переменную CXXFLAGS явно. Я написал здесь еще и зависимость от самого Makefile, чтобы при редактировании -DTEST проходила перекомпиляция SubClass.o и дальше пересборка programm.
Вот результат
avp@avp-ubu1:tmake$ make clean
rm -rf programm *.o *~ *.bak a.out
avp@avp-ubu1:tmake$ make
g++ -O3 -pthread -c -o main.o main.cpp
g++ -O3 -pthread -c -DTEST SubClass.cpp
g++ -O3 -pthread -c -o SuperClass.o SuperClass.cpp
g++ -o programm main.o SubClass.o SuperClass.o -pthread
avp@avp-ubu1:tmake$ ./programm
f1()
f2(): xaxa
Теперь отредактируем Makefile, уберем -DTEST при компиляции SubClass.cpp
avp@avp-ubu1:tmake$ make
g++ -O3 -pthread -c SubClass.cpp
g++ -o programm main.o SubClass.o SuperClass.o -pthread
avp@avp-ubu1:tmake$ ./programm
f2(): xaxa
avp@avp-ubu1:tmake$
gnu/makeдля задач, не связанных с программированием вообще и наc[++]в частности. – aleksandr barakin Jun 30 '15 at 20:04