Пример makefile
Использование действий по умолчанию.
#default target — file edit
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
По умолчанию, make начинает с первого правила (не считая правил, имена целей у которых начинаются с ‘.‘). Это называется главной целью по умолчанию. В нашем случае это правило edit. Если файл edit новее чем объектные файлы, от которых он зависит, то ничего не произойдет. В противном случае, прежде чем make сможет полностью обработать это правило, он должен рекурсивно обработать правила для файлов, от которых зависит edit. Каждый из этих файлов обрабатывается в соответствии со своим собственным правилом. Перекомпиляция должна быть проведена, если исходный файл или любой из заголовочных файлов, упомянутых среди зависимостей, обновлен позднее, чем объектный файл, или если объектный файл не существует.
Правилу clean не соответствует никакого создаваемого файла и, соответственно, clean ни от чего не зависит и само не входит в список зависимостей. При запуске по умолчанию clean вызываться не будет. Для его выполнения необходимо явно указать цель при запуске make: make clean
Для сокращения записи можно использовать переменные и действия по умолчанию (неявные правила)
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
-rm edit $(objects)
Переменная objects позволила использовать единожды написанный список объектных файлов, а для объектных файлов в make встроено неявное правило по умолчанию
Специальная цель .PHONY является встроенной в make и определяет свои зависимости как цели-имена, которым нет соответствия в виде файлов. Если данное правило пропустить, то создание в текущем каталоге файла с именем clean заблокирует выполнение make clean.
Использование правил по умолчанию позволяет изменить стиль записей зависимостей:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
Данная запись указывает, что все объектные файлы зависят от заголовочного файла defs.h, но для некоторых из них проверяются дополнительные зависимости.
parallel.uran.ru
Makefile — файл, содержащий набор инструкций для программы make. Программа make с помощью этого файла позволяет автоматизировать процесс компиляции программы и выполнять при этом различные действия. При запуске make по умолчанию ищет файл Makefile в текущей папке и обрабатывает его (можно изменить это поведение, чтобы открывался другой файл с набором инструкций, если ввести команду make -f другое_имя_makefile).
Система make родилась в мире UNIX и постепенно переползла и на Windows вместе с портами GNU-компиляторов (gcc). Если открыть пример готового Makefile, то он поначалу может показаться полной абракадаброй, поскольку содержимое файла подчиняется заранее заданному набору правил, которые необходимо предварительно изучить. Для простоты рассмотрим пример работы с проектом AVR и компилятором gcc.
Немного о структуре файла.
— Комментарии, как это принято в UNIX скриптах, начинаются с символа # и продолжаются до конца строки.
JTAGICEII = c:/Program Files/AtmelAVR 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 [4] на примере проекта из библиотеки V-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.rarSHELL=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/ARMmyproject autoname /pattern:YYMMDDhhmmss c:/archive/ARM/myproject/$(ARCHIVE) xcopy /M /Y c:/archive/ARMmyproject*.* "\serverWORK"
2. Сетевые (UNC) пути необходимо заключать в двойные кавычки, иначе они будут неправильно переданы интерпретатору cmd.exe. Вот так:
xcopy /M /Y c:/archive/ARMmyproject*.* "serverWORK"
3. Отлаживать makefile удобно с помощью команды echo, выводя в консоль значения переменных. Пример:
[Как создать простейший makefile]
Предположим, есть три файла: program.c, program.h и header.h. Нужно их скомпилировать компилятором gcc. Как это проще всего осуществить?
Очевидно, что нужно создать командный файл makefile, и передать его утилите make. Вот простое решение, демонстрирующее общую концепцию:
HEADERS = program.h header.h
default: program.exe
program.o: program.c $(HEADERS) gcc -c program.c -o program.o
program.exe: program.o gcc program.o -o program.exe
clean: -rm -f *.o *.exe
Обратите внимание, что вместо пробелов в начале строк должны быть символы табуляции, иначе makefile работать не будет. Это нужно исправить, когда будете копировать этот текст как шаблон нового makefile.
Это простейший шаблон, и недостаток у него в том, что если нужно поддерживать большое количество файлов кода, то для каждого файла нужно добавлять новое правило. Этот недостаток можно устранить так:
HEADERS = program.h headers.h
OBJECTS = program.o
default: program.exe
%.o: %.c $(HEADERS) gcc -c $< -o $@
program: $(OBJECTS) gcc $(OBJECTS) -o $@
clean: -rm -f $(OBJECTS) *.exe
Это простейший пример, и для упрощения здесь опущены такие макросы, как $(CC), $(CFLAGS) и другие. Вот пример несложного makefile, который я часто использую для компилирования исходного кода на языке C.
TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall
.PHONY: clean all default
default: $(TARGET)
all: default
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)
%.o: %.c $(HEADERS) $(CC) $(CFLAGS) -c $< -o $@
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS) $(CC) $(OBJECTS) -Wall $(LIBS) -o $@ clean: -rm -f *.o -rm -f $(TARGET)
В этом makefile используются функции wildcard и patsubst утилиты make для автоматического подключения файлов *.c и *.h в текущей директории. Это означает, что когда Вы добавляете новые модули исходного кода в корневой каталог проекта, то Вам уже не надо модифицировать содержимое makefile. Если Вы хотите поменять имя генерируемого исполняемого файла, то Вам нужно просто поменять значение переменной TARGET. Для очистки проекта нужно в корневом каталоге проекта ввести команду make clean, а для компиляции make all или просто make.
В любом случае, ИМХО, не стоит использовать Autoconf/Automake. Конечно, они хорошо работают, но если Вы к ним привыкнете, то не сможете делать самых простых вещей, и Вам будет трудно разобраться в содержимом готовых makefile, которые поставляются вместе с большинством open-source проектов.
addprefix. Функция addprefix позволяет добавить префикс с каждой строке в последовательности строк. Пример:
OBJDIR = Objects OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp)) @echo $(OBJECTS) # выведется trim.o main.o bmpfile.o OBJ = $(addprefix $(OBJDIR)/, $(OBJECTS)) @echo $(OBJ) # выведется Objects/trim.o Objects/main.o Objects/bmpfile.o
Утилита gccmakedep. В зависимости от количества заголовков и модулей проекта, и Ваших потребностей в разработке, рассмотрите возможность использования утилиты gccmakedep [7]. Эта программа анализирует текущий каталог, и добавляет в конец makefile зависимости от заголовков для каждого найденного файла *.c/*.cpp. Конечно, если у Вас в проекте только 2 или 3 файла, то такой функционал излишен, но если модулей и заголовков намного больше, то утилита gccmakedep может пригодиться.
[Ссылки]
1. Installing MSYS site:mingw.org.
2. Home of the MinGW and MSYS Projects site:mingw.org.
3. Перевод Makefile Mini HOWTO (make) site:opennet.ru.
4. Рабочий Makefile на примере AVR-USB (USB HID-устройство и консольная утилита для работы с ним).
5. GNU Make программа управления компиляцией site:linux.yaroslavl.ru (руководство по программе make на русском языке).
6. Эффективное использование GNU Make site:linux.org.ru.
microsin.net
Не редко необходимые пакеты можно найти только в виде исходных текстов, в данной статье описывается метод установки пакета из исходных текстов.
Программы обычно распространяются в упакованных архивах, это файлы с расширениями
<some_app_name>.tar.gz (иногда .tgz) <some_app_name>.tar.bz2
Нужно понимать отличие между архиватором и упаковщиком.
Для архивации директорий и файлов используется программа tar; результатом её работы является файл с расширением .tar. Грубо говоря, это копия файловой системы — директорий и файлов с их атрибутами и правами доступа, помещённая в один файл.
Данный файл по размеру будет чуть больше, чем суммарный размер файлов, которые были архивированы. Поэтому (а может и по другой причине) используют упаковщики — программы, которые позволяют уменьшить размер файла без потери данных.
Программа tar умеет распаковывать, поэтому не нужно вызывать gunzip, а можно просто указать программе tar, что файл нужно cначала распаковать. Например, команда
tar -xvf <some_app_name>.tar.gz
сразу распакует и разархивирует. Отличие файлов с расширениями
<some_app_name>.tar.gz
и
<some_app_name>.tar.bz2
лишь в том, что использовались разные упаковщики, программа tar определяет метод сжатия автоматически и дополнительных опций в данном случае не требуется.
После распаковки необходимо перейти в полученный каталог, все описываемые ниже команды выполняются в каталоге с исходными текстами пакета.
cd <имя_пакета>*
Для сборки программ в GNU/Linux используется (в основном) программа make, которая запускает инструкции из Makefile, но поскольку дистрибутивов GNU/Linux много, и они все разные, то для того чтобы собрать программу, нужно для каждого дистрибутива отдельно прописывать пути,где какие лежат библиотеки и заголовочные файлы. Программисты не могут изучать каждый дистрибутив и для каждого отдельно создавать Makefile. Поэтому придумали конфигураторы, которые «изучают» систему, и в соответствии с полученными знаниями создают Makefile. Но на конфигураторе они не остановились и придумали конфигураторы конфигураторов …на этом они остановились
Для сборки нам нужны компиляторы: они прописаны в зависимостях пакета build-essential, так что достаточно установить его со всеми зависимостями. Ещё нужны autoconf и automake.
Итак, чтобы собрать что-то из исходников, нужно сначала собрать конфигуратор; как собрать конфигуратор, описано в файле configure.in. Для сборки конфигуратора необходимо выполнить
./bootstrap
или
./autogen.sh
Если таких скриптов в архиве не оказалось, то можно выполнить последовательно следующие команды:
aclocal autoheader automake --gnu --add-missing --copy --foreign autoconf -f -Wall
Все эти команды используют файл configure.in. После выполнения этих команд создастся файл configure. После этого необходимо запустить конфигуратор для проверки наличия всех зависимостей, а также установки дополнительных опций сборки (если возможно) и просмотра результата установки (опционально- может не быть)
./configure
Конфигуратор построит Makefile основываясь на полученных знаниях и файле makefile.am. Можно передать конфигуратору опции, предусмотренные в исходниках программы, которые позволяют включать/отключать те или иные возможности программы, обычно узнать о них можно командой
./configure --help
Также есть набор стандартных опций, вроде
--prefix=
, которая указывает, какой каталог использовать для установки. Для Ubuntu обычно
--prefix=/usr
или
--prefix=/usr/local
БЕЗ слеша в конце! Теперь можно запустить процесс сборки самой программы командой
make
Для сборки достаточно привелегий обычного пользователя. Окончанием сборки можно считать момент, когда команды в консоли перестанут «беспорядочно» выполняться и не будет слова error. Теперь всё скомпилировано и готово для установки.
Усилия потраченные на Правильную установку
в последствии с лихвой окупятся в случае удаления или обновления устанавливаемого программного обеспечения.
Установка при помощи утилиты checkinstall. Для установки выполните
sudo apt-get install checkinstall
Минус данного способа: checkinstall понимает не все исходники, поскольку автор программы может написать особые скрипты по установке и checkinstall их не поймёт.
Для создания и установки deb-пакета необходимо выполнить
sudo checkinstall
Быстрое создание deb-пакета «вручную».
Основное отличие от предыдущего способа заключается в том, что в данном случае вы создаете пакет вручную и отслеживаете все вносимые изменения. Так же этот способ подойдет вам, если исходники не поддерживают сборку пакета с checkinstall.
fakeroot make install DESTDIR=`pwd`/tempinstall
сd tempinstall mkdir DEBIAN find etc | sed "s/^/\//" > DEBIAN/conffiles
Package: имя_пакета Version: 1.2.3 Architecture: amd64/i386/armel/all Maintainer: Можете вписать своё имя, можете дребедень, но если оставить пустым, то dpkg будет ругаться Depends: Тут можно вписать список пакетов через запятую. Priority: optional Description: Тоже надо что-нибудь вписать, чтобы не кидало предупреждения
При необходимости там же можно создать скрипты preinst, postinst, prerm и postrm.
Создаем deb-пакет, для чего выполняем:
dpkg -b tempinstall
sudo dpkg -i tempinstall.deb
Процедура создания deb-пакета подробно описана в данной статье.
Минус данного способа заключается в том, что если вы устанавливаете напрямую через make install, то нормально удалить или обновить пакет вы, скорее всего, не сможете. Более того, установка новой версии поверх старой, скорее всего, затрёт ваши изменения в конфигах. make install делает ровно то, что ему сказано — производит установку файлов в нужные места, игнорируя тот факт, что там что-то уже есть. После этого процесса совершенно никакой информации о том, что и куда ставилось, получить в удобоваримом виде невозможно. Иногда, конечно, Makefile поддерживает действие uninstall, но это встречается не так часто, да и не факт, что корректно работает. Кроме того, вам будет необходимо хранить для деинсталяции распакованное дерево исходников и правил сборки.
Для установки необходимо выполнить
sudo make install
Для удаления пакета, установленного данным способом необходимо выполнить в корневой директории исходников программы (там где вы запускали make install).
sudo make uninstall
Часто на этапе конфигурации конфигуратор сообщает, что нехватает той или иной библиотеки. Название библиотеки, которое он сообщает, не всегда соответствует названию пакета в Ubuntu. Из собственного опыта могу посоветовать поискать в Синаптике нужный пакет, исключив префикс lib, если нашлось несколько пакетов различающихся приставкой -dev в названии, то вам нужно установить именно -dev пакет (обычно он тянет за собой и не -dev пакет). Можно ещё поискать с помощью http://packages.ubuntu.com/, введя имя библиотеки в поиск по содержимому пакетов, аналогично, если найдётся dev и не dev, нужны оба . Ну или просто поискать в Google.
Пакеты с буквами mm в конце описания — это пакеты для C++ программ. Список для bmpx, но подойдёт почти для любой GTK2/Gnome программы. Так что если не получается собрать, то посмотрите на этот список и сверьте с тем что у вас установлено.
Compile: | Runtime: | |
---|---|---|
X | libx11-dev | libx11-6 |
GlibMM | libglibmm-2.4-dev | libglibmm-2.4-1c2a |
GTK+ | libgtk2.0-dev,gtk-doc-tools | libgtk2.0-0 |
GTKMM | libgtkmm-2.4-dev | libgtkmm-2.4-1c2a |
Glade | libglade2-dev | libglade2-0 |
GladeMM | libglademm-2.4-dev | libglademm-2.4-1c2a |
XML | libxml2-dev | libxml2 |
XML++ | libxml++2.6-dev | libxml++2.6c2a |
DBus | libdbus-1-dev,libdbus-glib-1-dev | libdbus-1-2,libdbus-glib-1-2 |
Alsa | libasound2-dev | libasound2 |
HAL | libhal-dev,libhal-storage-dev | libhal1,libhal-storage1 |
Gamin | libgamin-dev | libgamin0 |
Neon | libneon25-dev | libneon25 |
TagLib | libtagc0-dev | libtagc0 |
Startup-Notify | libstartup-notification0-dev | libstartup-notification0 |
Boost | libboost-dev,libboost-filesystem-dev | libboost-filesystem1.33.1 |
MusicBrainz | libmusicbrainz4-dev | libmusicbrainz4c2a |
GStreamer | libgstreamer0.10-dev,libgstreamer-plugins-base0.10-dev | libgstreamer0.10-0,libgstreamer-plugins-base0.10-0 |
help.ubuntu.ru
21.2. Сборочная утилита make
Если вы уже собирали прикладную программу из исходных кодов, то обратили внимание на стандартную последовательность команд: make; make install
.
Без утилиты make не обходится создание ни одного серьезного проекта. Эта утилита управляет сборкой большого проекта, состоящего из десятков и сотен файлов. Программа make может работать не только с компилятором gcc, но и с любым компилятором для любого языка программирования, способным запускаться из командной строки.
Директивы утилиты make служат для определения зависимостей между файлами проекта и находятся в файле по имени Makefile, расположенном в каталоге сборки.
Разберемся, как пишутся make-файлы. Общий формат make-файла выглядит так:
цель1: список_необходимых_файлов
последовательность_команд
...
цельN: список_необходимых_файлов
последовательностъ_команд
Цель — это метка для некоторой последовательности команд (например, install) или результирующий файл, который нужно «построить» — скомпилировать или скомпоновать.
Цели должны отделяться друг от друга хотя бы одной пустой строкой. Список необходимых файлов — это перечень файлов или других целей, которые нужны для достижения данной цели; он может быть и пустым.
Последовательность команд — это команды, которые нужно выполнить для достижения цели. Последовательность команд должна отделяться от начала строки символом табуляции, иначе вы получите ошибку «missing separator» (нет разделителя).
Make-файл может содержать комментарии — они начинаются символом #.
В make-файлах вы можете использовать макроопределения:
CC=gcc
PATH=/usr/include /usr/src/linux/include
MODFLAGS:= -O3 -Wall -DLINUX -I$(PATH)
...
$(CC) $(MODFLAGS) -c proga.c
Чтобы обратиться к макроопределению в команде или в другом макроопределении, нужно использовать конструкцию $(имя). Макроопределение может включать в себя другое, ранее определенное, макроопределение.
Формат запуска утилиты make:
make [-f файл] [ключи] [цель]
Ключ -f указывает файл инструкций, который нужно использовать вместо Makefile. Если этот ключ не указан, то make ищет в текущем каталоге файл Makefile и начинает собирать указанную цель. Если цель не указана, то выполняется первая встреченная в make-файле. Сборка выполняется рекурсивно: make сначала выполняет все цели, от которых зависит текущая цель. Если зависимость представляет собой файл, то make сравнивает его время последней модификации со временем целевого файла: если целевой файл старше или отсутствует, то будет выполнена указанная последовательность команд. Если целевой файл моложе, то текущая цель считается достигнутой.
Примечание
Если нужно избежать пересборки какого-то из файлов проекта, то можно искусственно «омолодить» его командой touch, которая присвоит ему в качестве времени последней модификации текущее время. Если нужно, наоборот, принудительно пересобрать цель, то следует «омолодить» один из файлов, от которых она зависит.
Работа программы make заканчивается, когда достигнута цель, указанная в командной строке. Обычно это цель all, собирающая все результирующие файлы проекта. Другими распространенными целями являются install (установить собранную программу) и clean (удалить ненужные файлы, созданные в процессе сборки).
В листинге 21.2 представлен make-файл, собирающий небольшой проект из двух программ client и server, каждая из которых компилируется из одного файла исходного кода.
Листинг 21.2. Примерный make-файл
CC=gcc
CFLAGS=-O
all: client server
client: client.с
$(CC) client.с -о client
server: server.с
$(CC) server.с -о server
Обычно при вызове утилиты make не нужно задавать никаких ключей. Но иногда использование ключей бывает очень кстати (таблица 21.1).
Ключи команды make Таблица 21.1
Ключ | Назначение |
---|---|
-C каталог | Перейти в указанный каталог перед началом работы |
-d | Вывод отладочной информации |
-e | Приоритет переменным окружения. Если у нас установлена переменная окружения CC и в Makefile есть переменная с таким же именем, то будет использована переменная окружения |
-f файл | Использовать указанный файл вместо Makefile |
-i | Игнорировать ошибки компилятора |
-I каталог | В указанном каталоге будет производиться поиск файлов, включаемых в Makefile |
-j n | Запускать не более n команд одновременно |
-k | Продолжить работу после ошибки, если это возможно |
-n | Вывести команды, которые должны были выполниться, но не выполнять их |
-о файл | Пропустить данный файл, даже если в Makefile указано, что он должен быть создан заново |
-r | Не использовать встроенные правила |
-s | Не выводить команды перед их выполнением |
-w | Вывод текущего каталога до и после выполнения команды |
Следующая глава >
it.wikireading.ru
Корневая рекурсивная идея Makefile:
Чтобы создать цель, нам нужны предварительные условия (другие цели!) и инструкции для сборки
Это файлы, папки или поддельные цели (обычно в .PHONY
). Файлы/папки проверяются на наличие и дату модификации.
Цель должна быть перестроена, если у нее нет предпосылки или если она старше того, что требуется для каких-либо предварительных условий.
Инструкция < команды оболочки, начиная с одной вкладки. Каждая строка команд представляет собой один экземпляр оболочки. Команда оболочки может быть продолжена на следующей строке, когда текущий заканчивается обратным слэшем \
.
Цель — это правило зависимость или .
Зависимость:
target : prerequisite1 prerequisite2 prerequisiteN
Правило:
target : prerequisite1 prerequisite2 prerequisiteN
instructions1
@hidden_batch2 ; \
hidden_batch3
С вкладками перед началом команды.
Отладка Makefile может стать настоящей головной болью.
Попробуйте следующее в вашем файле Makefile, чтобы показать трассировку (с расположением файла и строки для warning
):
$(info Shell: $(SHELL))
$(warning CXX: $(CXX))
Это полезно, если ваш Makefile содержит много вложенных if/else/endif
, и вы не уверены
больше того, что является текущим путем.
Идеальная структура файла makefile:
Реальная обработка целевых команд начинается после того, как весь файл Makefile и его включенные файлы
(хранится в внутренней базе данных make
).
Наконец, примените теорию к этому конкретному примеру, используя Boost и создайте поддельные исходные файлы для иллюстрации.
#include "rawr.h"
#include "rawr.h"
#include <iostream>
#include "rawr.h"
#include "simple_ls.h"
#include "2dquicksort.h"
#include <boost/array.hpp> // Boost!
int main(int argc, char **argv)
{
boost::array<int,4> a = { { 1, 2, 3, 4} };
std::cout << a[1] << std::endl;
return 0;
}
Не забудьте заменить пробелы реальными вкладками, если вы скопируете Makefile
источник из * стека *** переполнения **:
sed -i~ -e 's/^ /\t/' Makefile
Файл Makefile:
## Makefile for C++ project using Boost
#
# @author Cedric "levif" Le Dillau
#
# Some notes:
# - Using ':=' instead of '=' assign the value at Makefile parsing time,
# others are evaluated at usage time. This discards
# - Use ':set list' in Vi/Vim to show tabs (Ctrl-v-i force tab insertion)
#
# List to '.PHONY' all fake targets, those that are neither files nor folders.
# "all" and "clean" are good candidates.
.PHONY: all, clean
# Define the final program name
PROGNAME := converter
# Pre-processor flags to be used for includes (-I) and defines (-D)
CPPFLAGS := -DUSE_BOOST
# CFLAGS is used for C compilation options.
CFLAGS := -Wall -O0
# CXXFLAGS is used for C++ compilation options.
CXXFLAGS += -Wall -O0
# LDFLAGS is used for linker (-g enables debug symbols)
LDFLAGS += -g
# Which Boost modules to use (all)
BOOST_MODULES = \
date_time \
filesystem \
graph \
iostreams \
math_c99 \
system \
serialization \
regex
# Boost libraries' type (a suffix)
BOOST_MODULES_TYPE := -mt
# Define library names with their type
BOOST_MODULES_LIBS := $(addsuffix $(BOOT_MODULES_TYPE),$(BOOST_MODULES))
# Define the linker argument to use the Boost libraries.
BOOST_LDFLAGS := $(addprefix -lboost_,$(BOOST_MODULES_LIBS))
# Feed compiler/linker flags with Boost's
CPPFLAGS += $(BOOST_CPPFLAGS)
LDFLAGS += $(BOOST_LDFLAGS)
# List the project' sources to compile or let the Makefile recognize
# them for you using 'wildcard' function.
#
#SOURCES = simple_ls.cpp rawr.cpp converter.cpp
SOURCES = $(wildcard *.cpp)
# List the project' headers or let the Makefile recognize
# them for you using 'wildcard' function.
#
#HEADERS = simple_ls.h 2dquicksort.h rawr.h
HEADERS = $(wildcard %.h)
# Construct the list of object files based on source files using
# simple extension substitution.
OBJECTS = $(SOURCES:%.cpp=%.o)
#
# Now declare the dependencies rules and targets
#
# Starting with 'all' make it becomes the default target when none
# is specified on 'make' command line.
all : $(PROGNAME)
# Declare that the final program depends on all objects and the Makfile
$(PROGNAME) : $(OBJECTS) Makefile
$(CXX) -o $@ $(LDFLAGS) $(OBJECTS)
# Now the choice of using implicit rules or not (my choice)...
#
# Choice 1: use implicit rules and then we only need to add some dependencies
# to each object.
#
## Tells make that each object file depends on all headers and this Makefile.
#$(OBJECTS) : $(HEADERS) Makefile
#
# Choice 2: don't use implicit rules and specify our will
%.o: %.cpp $(HEADERS) Makefile
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<
# Simple clean-up target
# notes:
# - the '@' before 'echo' informs make to hide command invocation.
# - the '-' before 'rm' command to informs make to ignore errors.
clean :
@echo "Clean."
-rm -f *.o $(PROGNAME)
2dquicksort.h
converter.cpp
Makefile
rawr.cpp
rawr.h
simple_ls.cpp
simple_ls.h
make clean all
Clean.
rm -f *.o converter
g++ -Wall -O0 -DUSE_BOOST -c -o converter.o converter.cpp
g++ -Wall -O0 -DUSE_BOOST -c -o rawr.o rawr.cpp
g++ -Wall -O0 -DUSE_BOOST -c -o simple_ls.o simple_ls.cpp
g++ -o converter -g -lboost_date_time -lboost_filesystem -lboost_graph -lboost_iostreams -lboost_math_c99 -lboost_system -lboost_serialization -lboost_regex converter.o rawr.o simple_ls.o
И теперь результат почти самой крошечной программы Boost:
./converter
2
Нет оправдания, чтобы не использовать его! Boost — это действительно набор инструментов С++:)
qaru.site
Короче говоря, когда я запускаю команду make
она говорит:
Я заглянул в папку-xf86-video-intel-2.17.0, и есть файл с именем «Makefile.in», который должен быть в файле, не так ли?
Это происходит потому, что в этом каталоге нет файла с именем Makefile . Чтобы создать этот Makefile, вам необходимо выполнить
$ ./configure
Скрипт configure определяет, имеет ли ваша система все зависимости, необходимые для компиляции приложения. Если зависимость не найдена, configure завершится с ошибкой, и Makefile не будет создан. Чтобы решить эту проблему, вы должны установить все зависимости, необходимые для приложения.
Приложение xf86-video-intel, по-видимому, предоставляется пакетом xserver-xorg-video-intel, и его зависимости могут быть легко установлены путем запуска
$ sudo apt-get build-dep xserver-xorg-video-intel
Для получения дополнительной информации вы можете прочитать файлы README или INSTALL.
Команда make ищет файл под названием «Makefile», не расширение, а не «Makefile.in». Поскольку файл не найден, make не знает, что делать, и останавливается. (Сообщение об ошибке является загадочным, потому что в некоторых редких случаях make может угадать, что делать без фактического Makefile.)
Ознакомьтесь с инструкциями по компиляции вашей программы. Вероятно, сначала вам нужно запустить ./configure
. Этот скрипт создаст «Makefile» на основе вашей установки и «Makefile.in».
Вы можете временно отключить ивритский язык при поиске помощи в Интернете, просто запустите
LC_ALL=C make
Это даст вам сообщения на английском языке.
Просто помните, что для запуска файла ./configure
вам понадобился компилятор. Так что сделайте что-нибудь вроде sudo apt-get install gcc
. затем снова запустите ./configure
и должен работать
Не волнуйтесь .. Есть только некоторые пакеты, которые необходимо установить. Введите «sudo synaptic» в терминале и введите .. в поле ввода типа «qt4-qmake» и отметьте для установки. то же, что и выше, поиск «libqt4-dev» и «libxml2-dev» и сделать один и тот же знак для установки одновременно .. затем применить без проверки вариант загрузки. здесь это …. Затем перейдите в каталог cd netanim и введите «make clean» и введите, если он не работает, введите «qmake NetAnim.pro» и введите его, он занимает пару секунд. затем введите «make» и введите … Здесь его сделано, это займет меньше минуты. Теперь в netanim введите тип ./NetAnim и введите.
Здесь вы увидите интерфейс анимации. Удачи
ubuntu.fliplinux.com
Не знакомы с libssh, но ошибка может быть, потому что среда настраивается по-другому, так что выполнение make через оболочку явно может помочь.
Попробуйте изменить команду (make
?) На
bash -c make
Если это не сработает, попробуйте
bash -c "export > env.txt ; make > make_out.txt 2> make_err.txt"
Затем проверьте, появились ли эти файлы и что они содержат, что должно давать хорошие подсказки.
Если у вас есть рабочий и нерабочий случай, то получите эти файлы из обоих случаев и сравните их (например, с diff -u
).
И измените bash
на любую используемую вами оболочку (и в этом случае проверьте, является ли -c
правильным переключателем, чтобы дать командную строку, и если export
является правильной командой для отображения среды), если вы не используете bash.
Основываясь на комментариях ниже: Разница в env.txt может быть, потому что некоторые из переменных окружения устанавливаются только для интерактивных оболочек. Например, в моем поле Ubuntu начало.bashrc имеет строки, подобные этому:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Теперь, если какая-либо из этих необходимых переменных окружения задана в.bashrc после этой строки, а ваше ssh-соединение не является интерактивным (без псевдо-tty), они не будут установлены.
Если это так, переместите эти переменные env в ~/.profile
или в ~/.bashrc
перед таким тестом, как указано выше. Также сделайте man bash
и прочитайте материал об файлах инициализации (например, ~/.bashrc
).
Другим решением было бы сделать интерактивный ssh-сеанс, который, на мой взгляд, документирован на этой странице для libssh: http://api.libssh.org/master/libssh_tutor_shell.html.
qaru.site