8-900-374-94-44
[email protected]
Slide Image
Меню

Как запустить makefile linux – Makefile для самых маленьких / Habr

Инструментарий программиста в Linux: MAKE

Пример 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 встроено неявное правило по умолчанию

file.c: file.o   cc -c file.c

Специальная цель .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 и что это такое? | avr

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/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.

7. gccmakedep site:x.org.

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. Теперь всё скомпилировано и готово для установки.

Усилия потраченные на Правильную установку в последствии с лихвой окупятся в случае удаления или обновления устанавливаемого программного обеспечения.

Правильная установка(Вариант №1)

Установка при помощи утилиты checkinstall. Для установки выполните

sudo apt-get install checkinstall

Минус данного способа: checkinstall понимает не все исходники, поскольку автор программы может написать особые скрипты по установке и checkinstall их не поймёт.

Для создания и установки deb-пакета необходимо выполнить

sudo checkinstall

Правильная установка(Вариант №2)

Быстрое создание 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

Установка (вариант №3)

Процедура создания 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:
Xlibx11-devlibx11-6
GlibMMlibglibmm-2.4-devlibglibmm-2.4-1c2a
GTK+libgtk2.0-dev,gtk-doc-toolslibgtk2.0-0
GTKMMlibgtkmm-2.4-devlibgtkmm-2.4-1c2a
Gladelibglade2-devlibglade2-0
GladeMMlibglademm-2.4-devlibglademm-2.4-1c2a
XMLlibxml2-devlibxml2
XML++libxml++2.6-devlibxml++2.6c2a
DBuslibdbus-1-dev,libdbus-glib-1-devlibdbus-1-2,libdbus-glib-1-2
Alsalibasound2-devlibasound2
HALlibhal-dev,libhal-storage-devlibhal1,libhal-storage1
Gaminlibgamin-devlibgamin0
Neonlibneon25-devlibneon25
TagLiblibtagc0-devlibtagc0
Startup-Notifylibstartup-notification0-devlibstartup-notification0
Boostlibboost-dev,libboost-filesystem-devlibboost-filesystem1.33.1
MusicBrainzlibmusicbrainz4-devlibmusicbrainz4c2a
GStreamerlibgstreamer0.10-dev,libgstreamer-plugins-base0.10-devlibgstreamer0.10-0,libgstreamer-plugins-base0.10-0

help.ubuntu.ru

21.2. Сборочная утилита make. Linux: Полное руководство

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

c++ — Создать файл linux make/build

Корневая рекурсивная идея 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:

  • настройка переменной
  • объявления о назначении/зависимости

Реальная обработка целевых команд начинается после того, как весь файл Makefile и его включенные файлы (хранится в внутренней базе данных make).

Наконец, примените теорию к этому конкретному примеру, используя Boost и создайте поддельные исходные файлы для иллюстрации.

rawr.cpp

#include "rawr.h"

simple_ls.cpp

#include "rawr.h"

converter.cpp

#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

Не забудьте заменить пробелы реальными вкладками, если вы скопируете 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

*** Нет заданных целей и не найден файл makefile. Стоп.» Ubuntu Linux

Короче говоря, когда я запускаю команду 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

c++ — Как запустить makefile с помощью libssh?

Не знакомы с 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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *