В этой статье не рассказывается, как написать Makefile, но рассматривается подход «расслоения на основе целевых объектов» для понимания инструмента, определения дизайна или развертывания набора кода.
Содержание:
Самый простой синтаксис правила Makefile выглядит следующим образом
Чтобы объяснить, Makefile изначально использовался для решения проблемы компиляции языка C, поэтому он имеет очень тесную связь с C, но это не означает, что Makefile можно использовать только для решения проблемы компиляции C. У вас не возникнет проблем с Java, но очевидно, что с Java ant справляется лучше, чем Makefile. Но это детали.Если вы понимаете Makefile, понять ant не составит труда. Формат самого Makefile не является стандартным, и разные инструменты make имеют разные сведения о том, как написать сам Makefile. Эта статья знакомит с идеей и принципом работы этого инструмента, подробности вы должны прочитать в соответствующем руководстве.
Makefile решает проблему компиляции. Что не так с компиляцией? Скажем, например, у вас есть 3 файла C. Foo.c, bar.c, main.c — это три файла C, если вы хотите скомпилировать их в app.exe, у вас будет следующая команда:
Согласно практике программистов Unix, любая команда, которая будет выполняться снова и снова, должна быть написана в виде сценария и стать «действием». Таким образом, вы запишете приведенную выше последовательность команд в build.sh, и вам нужно будет только выполнять этот скрипт каждый раз при компиляции, и проблема будет решена.
Тем не менее, с этим сценарием все еще существует проблема, если предположить, что я модифицировал foo.c, но не изменил bar.c и main.c, то выполнение этого скрипта будет расточительным, поскольку он безоговорочно перекомпилирует bar.c и main.c. .
Итак, более разумный способ написать этот скрипт должен быть таким:
Это сложно, не так ли? Также согласно общему стилю программистов Unix, если вы столкнулись с проблемой, не пытайтесь переопределить проблему, а посмотрите, что является дополнительной проблемой по сравнению с исходной проблемой, и попытайтесь решить дополнительную проблему. Так что здесь дополнительная проблема заключается в сравнении времени модификации файла. Это основная проблема, которую должен решить Makefile. Мы определяем новый «язык сценариев» (только интерпретируемый не sh/bash/tch, а make), который можно использовать для иллюстрации сравнения файлов, которое нам нужно сделать, очень простым способом. Таким образом, приведенный выше скрипт можно записать так:
Это исходная проблема, которую решают файлы Makefile. Makefile не обязателен, но может избавить вас от многих проблем.
Инструменту Make требуется файл makefile, чтобы указать Make, как работать. В общем, makefile сообщает Make, как компилировать и компоновать программу.
Принцип создания файла обновления:
1. Каждый измененный исходный файл C должен быть перекомпилирован
2. Если заголовочный файл изменен, все исходные файлы C, содержащие этот заголовочный файл, необходимо перекомпилировать.
3. Каждый исходный файл C компилируется для создания соответствующего объектного файла (файл obj, как правило, с тем же именем, что и исходный файл, с суффиксом .o).
4. Всякий раз, когда любой исходный файл C перекомпилируется, все объектные файлы должны быть повторно связаны для создания нового исполняемого файла.
Необходимо понимать вышеприведенные четыре принципа.Когда мы пишем make-файлы, мы должны следовать вышеперечисленным принципам.
Самый простой синтаксис правила Makefile выглядит следующим образом:
Каждое правило обычно состоит из одной или нескольких целей (целей), предпосылок (зависимостей) и рецептов (предписаний). Когда Make решает, выполнять ли рецепт в этом правиле, сравнивая старые и новые цели и предпосылки, если предпосылки новее, чем дата модификации цели, рецепт будет выполнен, иначе рецепт в правиле не будет быть казненным. Стоит отметить один момент: перед каждым рецептом должна быть добавлена вкладка.
1. В правиле, целью которого является редактирование, '' используется для разделения длинной строки на две для удобства чтения.
2. По умолчанию Make начинает выполняться с первого правила Makefile по умолчанию, то есть, когда мы только вводим «make» в оболочке и нажимаем Enter, make автоматически обращается к Makefile в текущем каталоге и запускает from Первое из этих правил начинает выполняться. Конечно, мы также можем указать правила для запуска выполнения
Пример: make clean //Начать выполнение с правила, целью которого является clean
3. Когда первое редактирование правила начинает выполняться по умолчанию, поскольку цель зависит от некоторых файлов .o, а эти файлы .o имеют свои собственные правила обновления, оно сначала инициирует выполнение собственных правил обновления файла .o, и, наконец, вернитесь к выполнению редактирования. Вы можете думать об этом как о рекурсивном процессе.
4. Очевидно, что поскольку цель clean не является зависимостью какой-либо другой цели и не является целью первого правила, то, если не указано, что оно должно начинаться с этого правила, это правило никогда не будет выполнено, аналогично из-за clean Правило не имеет зависимостей, и выполнение этого правила никогда не вызовет выполнение других правил.
Правила являются важной частью Makefile, и Make решает, как обновлять файлы проекта, читая правила в Makefile. В целом правило делится на три части: цель, предпосылки и рецепт.
Если вы не укажете, какое правило выполнять, Make всегда выполняет первое правило в файле.Кроме того, порядок записи других правил не влияет на порядок выполнения (Make выполняет требуемые правила только тогда, когда это необходимо. чем в порядке написания).
Хотя первое правило в Makefile выполняется первым, часто оно выполняется последним, поскольку часть зависимостей в первом правиле часто имеет свои собственные правила обновления, а зависимости в правилах обновления имеют соответствующие правила обновления, рекурсивно первое правило запускает выполнение других правил, и после выполнения других правил оно возвращается к первому правилу для продолжения выполнения. То же самое верно и при компиляции программы. Мы всегда сначала компилируем каждый подфайл, а затем соединяем их обратно, чтобы сформировать программу. Поэтому первое правило в Makefile обычно используется для запуска компиляции всей программы (и первое Цель правила обычно называется: все, что означает обновить весь проект)
В правиле вы можете использовать «$» для вызова определенной переменной (если вы действительно хотите ввести «$» вместо ссылки на переменную, вам нужно ввести «$$».
Каждое правило имеет свои рецепты, состоящие из одной или нескольких команд оболочки и выполняемые в том порядке, в котором они написаны. Обычно результатом выполнения является обновление цели.По умолчанию /bin/sh вызывается для выполнения команды оболочки, которую можно изменить вручную.
Другими словами, в Makefile есть как инструкции оболочки, так и собственные операторы make-файла, поэтому make-файл следует двум синтаксисам: использовать синтаксис оболочки в рецептах и следовать собственному синтаксису make-файла в других частях. make выполняет только ограниченную обработку рецептов в make-файле, а затем отправляет их в оболочку для выполнения.
На что обратить внимание при написании рецептов:
a. lКаждый рецепт обычно начинается с символов [TAB], конечно есть и другие способы написания, но я думаю этого пока достаточно
b. lПустая строка, начинающаяся с [TAB], также является рецептом, называемым пустым рецептом.
c. lСодержимое после «#» в рецепте не будет использоваться в качестве комментария, а будет передано в оболочку без изменений.
d. lНачиная с [TAB], переменные, определенные в рецепте, также будут переданы в оболочку как неизмененные переменные оболочки, а не как переменные в make-файле.