Make-Файлы Руководство
Опции: -f file - явное задание имени make-файла, если задание опущено, то ищутся файлы GNUmakefile, makefile или Makefile. Правила написания Makefile. Порядок правил несущественен. По умолчанию главной целью make является цель первого правила в первом make-файле. Если в первом правиле есть несколько целей, то только первая цель берется в качестве цели по умолчанию. Данное руководство предназначено для пользователей Salvo. Как использовать make-файлы.
Не очень строгий перевод материала Мне в свое время очень не хватило подобной методички для понимания базовых вещей о make. Думаю, будет хоть кому-нибудь интересно. Хотя эта технология и отмирает, но все равно используется в очень многих проектах. Кармы на хаб «Переводы» не хватило, как только появится возможность — добавлю и туда. Добавил в Переводы. Если есть ошибки в оформлении, то прошу указать на них. Буду исправлять.
Статья будет интересная прежде всего изучающим программирование на C/C в UNIX-подобных системах от самых корней, без использования IDE. Компилировать проект ручками — занятие весьма утомительное, особенно когда исходных файлов становится больше одного, и для каждого из них надо каждый раз набивать команды компиляции и линковки. Но не все так плохо.
Сейчас мы будем учиться создавать и использовать Мейкфайлы. Makefile — это набор инструкций для программы make, которая помогает собирать программный проект буквально в одно касание. Для практики понадобится создать микроскопический проект а-ля Hello World из четырех файлов в одном каталоге. Void printhello; int factorial(int n); Все скопом можно скачать Автор использовал язык C, знать который совсем не обязательно, и компилятор g из gcc. Любой другой компилятор скорее всего тоже подойдет.
Файлы слегка подправлены, чтобы собирались gcc 4.7.1 Программа make Если запустить make то программа попытается найти файл с именем по умолчание Makefile в текущем каталоге и выполнить инструкции из него. Если в текущем каталоге есть несколько мейкфайлов, то можно указать на нужный вот таким образом: make -f MyMakefile Есть еще множество других параметров, нам пока не нужных. О них можно узнать в ман-странице.
Процесс сборки Компилятор берет файлы с исходным кодом и получает из них объектные файлы. Затем линковщик берет объектные файлы и получает из них исполняемый файл. Сборка = компиляция + линковка. Компиляция руками Самый простой способ собрать программу: g main.cpp hello.cpp factorial.cpp -o hello Каждый раз набирать такое неудобно, поэтому будем автоматизировать. Самый простой Мейкфайл В нем должны быть такие части: цель: зависимости tab команда Для нашего примера мейкфайл будет выглядеть так: all: g main.cpp hello.cpp factorial.cpp -o hello Обратите внимание, что строка с командой должна начинаться с табуляции! Сохраните это под именем Makefile-1 в каталоге с проектом и запустите сборку командой make -f Makefile-1 В первом примере цель называется all.
Make-файлы Руководство Пользователя
Это цель по умолчанию для мейкфайла, которая будет выполняться, если никакая другая цель не указана явно. Также у этой цели в этом примере нет никаких зависимостей, так что make сразу приступает к выполнению нужной команды. А команда в свою очередь запускает компилятор.
Использование зависимостей Использовать несколько целей в одном мейкфайле полезно для больших проектов. Это связано с тем, что при изменении одного файла не понадобится пересобирать весь проект, а можно будет обойтись пересборкой только измененной части. Пример: all: hello hello: main.o factorial.o hello.o g main.o factorial.o hello.o -o hello main.o: main.cpp g -c main.cpp factorial.o: factorial.cpp g -c factorial.cpp hello.o: hello.cpp g -c hello.cpp clean: rm -rf.o hello Это надо сохранить под именем Makefile-2 все в том же каталоге Теперь у цели all есть только зависимость, но нет команды. В этом случае make при вызове последовательно выполнит все указанные в файле зависимости этой цели. Еще добавилась новая цель clean. Она традиционно используется для быстрой очистки всех результатов сборки проекта.
Make-файлы Руководство По Эксплуатации
Очистка запускается так: make -f Makefile-2 clean Использование переменных и комментариев Переменные широко используются в мейкфайлах. Например, это удобный способ учесть возможность того, что проект будут собирать другим компилятором или с другими опциями. # Это комментарий, который говорит, что переменная CC указывает компилятор, используемый для сборки CC=g #Это еще один комментарий. Он поясняет, что в переменной CFLAGS лежат флаги, которые передаются компилятору CFLAGS=-c -Wall all: hello hello: main.o factorial.o hello.o $(CC) main.o factorial.o hello.o -o hello main.o: main.cpp $(CC) $(CFLAGS) main.cpp factorial.o: factorial.cpp $(CC) $(CFLAGS) factorial.cpp hello.o: hello.cpp $(CC) $(CFLAGS) hello.cpp clean: rm -rf.o hello Это Makefile-3 Переменные — очень удобная штука. Для их использования надо просто присвоить им значение до момента их использования. После этого можно подставлять их значение в нужное место вот таким способом: $(VAR) Что делать дальше После этого краткого инструктажа уже можно пробовать создавать простые мейкфайлы самостоятельно. Дальше надо читать серьезные учебники и руководства.
Как финальный аккорд можно попробовать самостоятельно разобрать и осознать такой универсальный мейкфайл, который можно в два касания адаптировать под практически любой проект: CC=g CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@.cpp.o: $(CC) $(CFLAGS) $. Вы даже не проверяли то, о чём говорите. Ровно до тех пор, пока не появится необходимость подключить проекту объектный модуль. Соответственно, для этого модуля не будет.cpp-файла.Только что создал файл x.c, вручную скомпилировал в z.o, и добавил z.o в список целей сборки одного моего личного проекта — собирается нормально, никаких проблем у make не возникло со сборкой. Я даже успешно вызвал из кода на D функцию из z.o. Более того, может появится необходимость подключить один единственный файл.c и make тоже поломается.Опять же, никаких проблем:.d.o: $(DCOMPILER) $(DCOMPILERFLAGS) -c -of$@ $. В первом примере цель называется all.
Это цель по умолчанию для мейкфайла, которая будет выполняться, если никакая другая цель не указана явно.Тут злостно нарушена причинно-следственная связь! На самом деле, «по умолчанию» цель выбирается не «all», а просто первая цель в Makefile'е. Называться-то она может вообще как угодно: firsttarget: echo 'The first one is the default' all: echo 'All is the default' Проверяем: $ make echo 'The first one is the default' The first one is the default Понимаю, что это перевод, но своя голова-то тоже не бывает лишней:-) Из той же серии: all: g main.cpp hello.cpp factorial.cpp -o hello — правилом хорошего тона вроде как считается называть цель так же, как называется результат выполняния команд (hello). Могу поверить, что стилистическая ошибка в последнем примере обусловлена непониманием, описанным выше.