Я узнаю, как сделать Makefile
в g++. Я использую следующий пример. Коды для проекта здесь. Это Makefile
# Makefile for Writing Make Files Example
# *****************************************************
# Variables to control Makefile operation
CXX = g++
CXXFLAGS = -Wall -g
# ****************************************************
# Targets needed to bring the executable up to date
main: main.o Point.o Rectangle.o # ***Statement : 1
$(CXX) $(CXXFLAGS) -o main main.o Point.o Rectangle.o #Commands underneath dependencies have tabs before them
# The main.o target can be written more simply
main.o: Point.h Rectangle.h # ***Statement : 2
$(CXX) $(CXXFLAGS) -c main.cpp
Point.o: Point.h # ***Statement : 3
Rectangle.o: Rectangle.h Point.h # ***Statement : 4
Теперь у меня есть некоторые вопросы относительно этого, я также ссылался на конкретные строки, используя ключевое слово statement для удобства опроса.
1- Насколько я понимаю ваше утверждение 1. Когда g++ встречает main.o (который является зависимостью для target main.o) после main: он переходит к target main.0 (утверждение 2). Затем он проверяет зависимость main.o, если зависимость (два файла заголовка найдены), тогда она запускает команду. Затем она возвращается, чтобы выполнить свою задачу для следующей зависимости и так далее?
2-для зависимости Point.o, который является Point.h, почему нет команды как таковой
$(CXX) $(CXXFLAGS) -c Point.cpp
и аналогично для Rectangle.o почему нет никакой команды для своей зависимости как таковой
$ (CXX) $ (CXXFLAGS) -c Rectangle.cpp
Буду признателен, если кто-нибудь сможет это прояснить.
Верный. Стоит отметить, что gnu make
использует время модификации, чтобы определить, удовлетворяются ли зависимости.
make
имеет неявные правила для создания объектов .o
. Они используют переменные, такие как $CXX
и $CXXFLAGS
. Для данной цели, скажем, foo.o
, make
будет применять правило в зависимости от наличия исходного файла foo.<ext>
, создавая парную целевую зависимость foo.o: foo.<ext>
. Если расширение является C++ (например, .cpp
, .cc
, .C
), тогда оно будет применять правило вдоль строк
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c
Вы указали дополнительную зависимость для Point.o
. Это добавляется к неявной зависимости Point.cpp
. Если время модификации Point.h
или Point.cpp
новее, чем время Point.o
, правило будет запущено.
Как отметил @Basile в комментариях, вы можете вызвать make
с параметрами -p
или --print-data-base
, чтобы получить информацию о "состоянии" make, включая неявные правила. Например, используя его с grep, я могу запросить неявные правила для создания файлов .o
из файлов C++:
make -p | grep -A 1 -B 1 COMPILE.cc
Вывод:
# default
COMPILE.cpp = $(COMPILE.cc)
# makefile (from 'Makefile', line 1)
--
--
# default
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
# environment
--
--
# default
COMPILE.C = $(COMPILE.cc)
# environment
--
--
# commands to execute (built-in):
$(COMPILE.cc) $(OUTPUT_OPTION) $<
--
--
# commands to execute (built-in):
$(COMPILE.cc) $(OUTPUT_OPTION) $<
Что касается правила, которое вы продлили, Point.o: Point.h
, это будет моя версия make:
make -p | grep -A 1 -B 1 Point
....
Point.o: Point.cpp Point.h
# Implicit rule search has been done.
....
make -p
чтобы понять неявные правила.
xxx.cpp
как зависимости дляxxx.o
...