• I






      
           

Научно-популярный образовательный ресурс для юных и начинающих радиолюбителей - Popular science educational resource for young and novice hams

Основы электричества, учебные материалы и опыт профессионалов - Basics of electricity, educational materials and professional experience

КОНКУРС
language
 
Поиск junradio

Радиодетали
ОК
Сервисы

Stock Images
Покупка - продажа
Фото и изображений


 
Выгодный обмен
электронных валют

Друзья JR



JUNIOR RADIO

 

Как устроен Makefile



 
Makefile - файл, содержащий набор инструкций для программы make. Программа make с помощью этого файла позволяет автоматизировать процесс компиляции программы и выполнять при этом различные действия. При запуске make по умолчанию ищет файл Makefile в текущей папке и обрабатывает его (можно изменить это поведение, чтобы открывался другой файл с набором инструкций, если ввести команду make -f другое_имя_makefile).

Система make родилась в мире UNIX и постепенно переползла и на Windows вместе с портами GNU-компиляторов (gcc). Если открыть пример готового Makefile, то он поначалу может показаться полной абракадаброй, поскольку содержимое файла подчиняется заранее заданному набору правил, которые необходимо предварительно изучить. Для простоты рассмотрим пример работы с проектом AVR и компилятором gcc.

Немного о структуре файла.

- комментарии, как это принято в UNIX скриптах, начинаются с символа # и продолжаются до конца строки

- обычно в файле содержатся метки, идентифицирующие "цели" (targets, см. далее). Метка начинается с начала строки и оканчивается двоеточием :. После двоеточия могут идти так называемые зависимости, dependencies (сразу непонятно, что это такое и для чего надо, но дальше по ходу дела станет яснее). Обычно это имена файлов, либо ссылки на цели.

- если в качестве dependencies указана последовательность целей, то они будут выполняться друг за другом.

- если в качестве dependencies указаны имена файлов (обычно объектных), то утилита make может проверить - нужно их компилировать, или нет (мне непонятно, как она проверяет, однако это работает). Например, если компилируется несколько исходных файлов в несколько объектных, то некоторые исходные файлы не требуется каждый раз перекомпилировать заново, если они не изменялись. Для больших проектов это важно, поскольку существенно экономит время сборки программы (в нашем случае - получение двоичной прошивки для AVR).

- для упрощения содержимого Makefile и для удобства используются переменные. Пример задания переменной (здесь в переменную записана командная строка вызова программатора):

JTAGICEII = c:\Program Files\Atmel\AVR Tools\JTAGICEmkII\jtagiceii.exe -d $(DEVICE) -e -mi

После задания переменной на неё можно ссылаться так:

flash: main.hex
    $(JTAGICEII) -pf -if main.hex

- после задания в одной строке цели (цель: [зависимость1] .. [зависимостьN]) в последующих строках могут задаваться так называемые правила (rules). Каждое правило должно ОБЯЗАТЕЛЬНО начинаться с символа табуляции (таким способом make отслеживает правила и другие цели). Правило - это просто обычная команда (вызов компилятора, копирование, удаление и проч.), выполняемая шеллом.

- переменные $@, $<, $^ называются автоматическими (automatic variables).
$@ заменяется на текущую цель.
$< которая заменяется на первую зависимость из списка.
$^ которая заменяется на список всех зависимостей с их каталогами.

Итак, при работе с проектом может потребоваться автоматизировать следующие часто повторяющиеся действия:

1. Компиляция программы (вводимая команда будет выглядеть как make hex).
2
. Запись двоичного файла (make flash).
3
. Запись бит "перемычек" (make fuse, для микроконтроллеров AVR это обычно 2 байта).
4
. Полная запись микроконтроллера (и памяти и перемычек), выполняются действия и 2, и 3.
5
. Очистка проекта - удаление всех промежуточных файлов, образующихся при компиляции, обычно объектных (make clean).
6
. Стирание микроконтроллера (очистка flash и сброс перемычек в исходное состояние).
7
. Бэкап проекта (make backup), будет выполняться цель 5 (clean), а затем архивирование файлов.
8
. Вывод подсказки по возможным вариантам работы с проектом (просто make, при этом выводится подсказка по make hex, make flash, make fuse, make clean).

Для каждого такого действия 1..8 в Makefile прописывается блок команд, этот блок идентифицируется целью (target). Имя цели по сути является меткой, по которой переходит управление при обработке команды, переданной программе make. Для действия 1 это будет запуск компилятора (цель hex), для 2 - вызов программатора  (цель flash) и т. д. Рассмотрим для примера ветку обработки цели hex (команда make hex) по шагам - см. рабочий Makefile на примере AVR-USB.

1. Пользователь вводит команду make hex.
2
. Программа make открывает файл Makefile, ищет цель hex и начинает её обработку.
3
. Для цели hex указана зависимость main.hex и ни одного правила (строка 131). Программа make ищет цель main.hex и начинает её обработку.
4
. Для цели main.hex указана зависимость main.elf (строка 175) и несколько правил. Программа make ищет цель main.elf и начинает её обработку (правила цели main.hex будут отрабатываться после окончания обработки цели main.elf).
5
. Для цели main.elf указаны зависимости usbdrv и $(OBJECTS) (строка 172), а также одно правило (вызов компилятора для получения файла main.elf). Программа make ищет цель usbdrv и начинает её обработку.
6
. Для цели usbdrv не указано зависимостей (строка 169), только одно правило (копирование папки usbdrv в текущий каталог). Выполняется это правило, цель usbdrv завершена и происходит возврат к обработке цели main.elf.
7
. Зависимости, входящие в переменную $(OBJECTS) (строка 172), не являются целями, это просто имена файлов, которые должны быть получены при компиляции. Поэтому сразу начинается выполняться правило, запускающее компилятор (строка 173). В результате те объектные файлы, которые должны быть скомпилированы, появляются в соответствующих каталогах, и появляется выходной файл main.elf (двоичный файл, который может использоваться в качестве входного для эмулятора или симулятора при отладке программы). Цель main.elf завершена, происходит возврат к обработке цели main.hex (строка 175).
8
. Начинается обработка правил цели main.hex. Команда rm удаляет старые файлы прошивок flash и eeprom, avr-objcopy генерирует новую прошивку main.hex из файла main.elf, avr-size просто отображает информацию о размере секций в файле main.hex. Обработка цели main.hex закончена, происходит возврат к обработке цели hex.
9
. Все зависимости цели hex обработаны, правил у цели hex нет. Работа make на этом завершается.

Есть утилиты-визарды для автоматической генерации файлов Makefile, например входящая в пакет WinAVR утилита MFile (запускается ярлычком C:\WinAVR-к примеру 20080610\bin\wish84.exe mfile.tcl).

[Проблемы и их решение]

1. Makefile в среде Windows (Makefile работает при помощи пакета MSYS) завершается с ошибкой на команде xcopy, например (выполнение команды make backup):
/usr/bin/sh: -c: line 3: syntax error: unexpected end of file
make: *** [backup] Error 258

Проблема решается добавлением в начало Makefile строки "SHELL=cmd.exe". Вот пример рабочего Makefile, в котором эта ошибка устранена:

RAR = "c:/Program Files/WinRAR/WinRAR.exe"
ARCHIVE = myproject.rar
SHELL=cmd.exe

help:
    @echo "This Makefile has no default rule. Use one of the following:"
    @echo "make backup .... backup project"

backup:
    $(RAR) a -r -dh -ep1 $(ARCHIVE) ../myproject

    mv $(ARCHIVE) c:\archive\ARM\myproject
    autoname /pattern:YYMMDDhhmmss c:/archive/ARM/myproject/$(ARCHIVE)
    xcopy /M /Y c:\archive\ARM\myproject\*.*
"\\server\WORK\"

2. Сетевые (UNC) пути необходимо заключать в двойные кавычки, иначе они будут неправильно переданы интерпретатору cmd.exe. Вот так:

xcopy /M /Y c:\archive\ARM\myproject\*.* "\\server\WORK\"

Вроде все




Необходимо добавить материалы...
Результат опроса Результаты Все опросы нашего сайта Архив опросов
Всего голосовало: 372



          

Радио для всех© 2024