Что делает «make install»?
Переходя с Windows на Linux, я не могу понять процесс установки программного обеспечения в Linux. В Windows, когда мы запускаем установочный файл, он спрашивает, куда вы хотите установить программу, скорее всего, только в папке программных файлов. Позже он редактирует реестр. Это называется установкой в Windows. Что именно означает «установка программного обеспечения» в Linux?
Предположим, я скачал исходный код, настроил его, а затем собрал бинарный файл, используя make . Теперь это просто бинарная, а не полезная программа. Как это будет установлено? По make install ? И что именно делает эта команда?
Make — программа общего назначения, обычно используемая для компиляции. Но это может быть использовано для чего угодно.
Когда вы делаете что-то вроде «make all», программа make выполняет правило с именем «all» из файла в текущем каталоге с именем «Makefile». Это правило обычно вызывает компилятор для компиляции некоторого исходного кода в двоичные файлы.
Когда вы делаете «make install», программа make берет двоичные файлы из предыдущего шага и копирует их в некоторые подходящие места, чтобы к ним можно было получить доступ. В отличие от Windows, установка требует только копирования некоторых библиотек и исполняемых файлов, и в этом случае требования к реестру отсутствуют. Короче говоря, «make install» просто копирует скомпилированные файлы в соответствующие места.
make install делает все, что Makefile хочет автор. Как правило, к этому моменту уже слишком поздно менять каталог установки, как это часто известно ранее , во время сборки, поэтому на файлы справки и файлы конфигурации можно ссылаться с правильными путями.
Многие проекты используют GNU Autotools, чтобы попытаться улучшить их переносимость между аппаратными средствами и операционными системами. (Различные варианты Unix используют немного разные заголовки для объявлений функций, которые немного отличаются от обычного пути — за исключением того, что большинству программ нужна та или иная из тех, которые объявлены в разных местах.)
Когда проект использует Автоинструменты, обычная мантра для его установки:
./configure , Как правило , позволяет использовать параметр командной строки , как —prefix /opt/apache или что — то подобное , чтобы указать другой путь к файлу. /usr/local/ это общее значение по умолчанию prefix . Локально построенному программному обеспечению гораздо проще жить в одном месте, а распространяемое программное обеспечение — в «главных каталогах»: /usr/ /bin/ и так далее. (Упаковщики очень осторожны, чтобы никогда не трогать файлы /usr/local/ — они знают, что это исключительно для системных администраторов.)
В любом случае, ./configure —prefix /path/to/new/prefix переменная будет установлена в том, Makefile что доступно при компиляции программы, изменении страниц руководства, чтобы они указывали на правильные местоположения для файлов, изменении файлов конфигурации и т. Д. Таким образом make , программное обеспечение будет создано специально для места установки, которое вы хотите, и make install установит его в это место.
Большинство программ могут работать даже без последнего make install шага — просто ./program_name часто их запускают. Это определенно вещь для каждого проекта — некоторые, например postfix , qmail и т. Д. Состоят из множества разных движущихся частей и полагаются на то, что они работают вместе. Другие, такие как ls или su могут быть достаточно автономными, чтобы нормально работать из каталога, в котором они были встроены. (Это не часто полезно, но иногда очень полезно.)
Однако не все проекты используют Autotools — они огромные , сложные и убогие в обслуживании. Написанные от руки Makefile гораздо проще писать, и я лично считаю, что просто распространять простое Makefile с доступными переменными конфигурации намного проще как для разработчиков, так и для пользователей. (Хотя ./configure ; make ; make install мантра действительно проста для пользователей, когда она работает.)
Источник
Configure Make Install
NB: Чем лучше Вы разбираетесь в C++, Linux и работе компиляторов — тем проще Вам будет разобраться с configure make install
Перед установкой
Сначала Вам скорее всего нужно скачать архив с программой, которую Вы хотите установить.
Например, команда для скачивания python3.7:
Затем распаковать архив
tar -xf Python-3.7.0.tgz
И перейти в только что распакованную директорию
В этой директории скорее всего будет находиться скрипт configure
Configure
configure — это не команда linux а скрипт, который обычно лежит в папке к configure
Означает, что означает что префикс установки /usr ,
Бинари уходят в usr/bin
libraries в usr/lib
Проверяется наличие всего необходимого
Создается файл MakeFile
—prefix=PREFIX — папка для установки программы, вместо /, например, может быть /usr/local/, тогда все файлы будут распространены не по основной файловой системе, а в /usr/local;
—bindir=DIR — папка для размещения исполняемых файлов, должна находится в PREFIX;
—libdir=DIR — папка для размещения и поиска библиотек по умолчанию, тоже в PREFIX;
—includedir=DIR — папка для размещения man страниц;
—disable-возможность — отключить указанную возможность;
—enable-возможность — включить возможность;
—with-библиотека — подобно enable активирует указанную библиотеку или заголовочный файл;
—without-библиотека — подобное disable отключает использование библиотеки.
.cpp файлы компилируются в .o файлы
один .h файл может использоваться несколькими .cpp файлами
makefile нужны для того чтобы печатать меньше названий файлов и опций вручную.
С их помощью можно делать build только тех файлов, которые изменились.
Make это инструмент, который вызывает компиллятор. Можно указать тот компиллятор который нужен именно Вам.
С помощью инструкций в makefile можно указать какие именно файлы нужно заново компилировать.
Рассмотрим пример из C++ .
В директории находятся три .cpp файла, два .h файла и три .o файла, оставшиеся от прошлой компиляции.
- Example.cpp , Example.o
- Second.cpp , Second.h , Second.o
- Third.cpp , Third.h , Third.o
Все они нужны для проекта и не могут быть объединены в один файл.
Известно, что Example.cpp включает в себя файл Second.h и других зависимостей не имеет.
Мы хотим, чтобы при изменении самого Example.cpp либо его зависимости Second.h начиналась новая компиляция Example.cpp а затем новый Example.o линковался со старыми Second.o и Third.o
Для этого напишем Makefile aomake
all: simple simple: Example.o Second.o Third.o g++ Example.o Second.o Third.o — Simple Example.o: Example.cpp Second.h g++ -c Example.cpp
Отступы нужно ставить табуляцией
Смотрим на последние две строки:
Если Second.h или Example.cpp (в который включен Second.h) изменились нужно компилировать файл Example.cpp после чего получается object файл Example.o и, как видно из первых двух строк — после обновления Example.o все object файлы линкуются.
Выигрыш в этой ситуации заключается в том, что нам не нужно было перекомпилировать Second.cpp и Third.cpp мы просто перелинковали уже существующие Second.o Third.o с новым Example.o
Чтобы запустить этот файл нужно к команде make добавить опцию f и название файла
У файла Second.cpp две зависимости: Second.h и Third.h
У файла Third.cpp только одна зависимость: Third.h
Учтём эти зависимости в нашем aomake
all: simple simple: Example.o Second.o Third.o g++ Example.o Second.o Third.o — Simple Second.o: Second.cpp Second.h Third.h g++ -c Second.cpp Third.o: Third.cpp Third.h g++ -c Third.cpp Example.o: Example.cpp Second.h g++ -c Example.cpp
Ещё одной полезной опцией является j
-j — jobs Определяет число работ — jobs (commands) которые запускаются одновременно.
Если указано больше чем одна -j опция, то применяться будет последняя.
Если -j опция дана без аргументов make не будет ограничивать количество работ запускаемых одновременно. То есть запуститься сможет неограниченное количество работ одновременно.
Более подробную информацию по Makefile вы можете найти в статье «makefile tutorial»
Install
Make — это не единственный способ устанавливать программы под linux. Более того, за сорок с лишним лет существования утилиты make вышло много её версий.
Прежде чем ставить что-то по-старинке с make install — советую изучить checkinstall
Источник
Просто о make
Меня всегда привлекал минимализм. Идея о том, что одна вещь должна выполнять одну функцию, но при этом выполнять ее как можно лучше, вылилась в создание UNIX. И хотя UNIX давно уже нельзя назвать простой системой, да и минимализм в ней узреть не так то просто, ее можно считать наглядным примером количество- качественной трансформации множества простых и понятных вещей в одну весьма непростую и не прозрачную. В своем развитии make прошел примерно такой же путь: простота и ясность, с ростом масштабов, превратилась в жуткого монстра (вспомните свои ощущения, когда впервые открыли мэйкфайл).
Мое упорное игнорирование make в течении долгого времени, было обусловлено удобством используемых IDE, и нежеланием разбираться в этом ‘пережитке прошлого’ (по сути — ленью). Однако, все эти надоедливые кнопочки, менюшки ит.п. атрибуты всевозможных студий, заставили меня искать альтернативу тому методу работы, который я практиковал до сих пор. Нет, я не стал гуру make, но полученных мною знаний вполне достаточно для моих небольших проектов. Данная статья предназначена для тех, кто так же как и я еще совсем недавно, желают вырваться из уютного оконного рабства в аскетичный, но свободный мир шелла.
Make- основные сведения
make — утилита предназначенная для автоматизации преобразования файлов из одной формы в другую. Правила преобразования задаются в скрипте с именем Makefile, который должен находиться в корне рабочей директории проекта. Сам скрипт состоит из набора правил, которые в свою очередь описываются:
1) целями (то, что данное правило делает);
2) реквизитами (то, что необходимо для выполнения правила и получения целей);
3) командами (выполняющими данные преобразования).
В общем виде синтаксис makefile можно представить так:
То есть, правило make это ответы на три вопроса:
Несложно заметить что процессы трансляции и компиляции очень красиво ложатся на эту схему:
Простейший Makefile
Предположим, у нас имеется программа, состоящая всего из одного файла:
Для его компиляции достаточно очень простого мэйкфайла:
Данный Makefile состоит из одного правила, которое в свою очередь состоит из цели — «hello», реквизита — «main.c», и команды — «gcc -o hello main.c». Теперь, для компиляции достаточно дать команду make в рабочем каталоге. По умолчанию make станет выполнять самое первое правило, если цель выполнения не была явно указана при вызове:
Компиляция из множества исходников
Предположим, что у нас имеется программа, состоящая из 2 файлов:
main.c
Makefile, выполняющий компиляцию этой программы может выглядеть так:
Он вполне работоспособен, однако имеет один значительный недостаток: какой — раскроем далее.
Инкрементная компиляция
Представим, что наша программа состоит из десятка- другого исходных файлов. Мы вносим изменения в один из них, и хотим ее пересобрать. Использование подхода описанного в предыдущем примере приведет к тому, что все без исключения исходные файлы будут снова скомпилированы, что негативно скажется на времени перекомпиляции. Решение — разделить компиляцию на два этапа: этап трансляции и этап линковки.
Теперь, после изменения одного из исходных файлов, достаточно произвести его трансляцию и линковку всех объектных файлов. При этом мы пропускаем этап трансляции не затронутых изменениями реквизитов, что сокращает время компиляции в целом. Такой подход называется инкрементной компиляцией. Для ее поддержки make сопоставляет время изменения целей и их реквизитов (используя данные файловой системы), благодаря чему самостоятельно решает какие правила следует выполнить, а какие можно просто проигнорировать:
Попробуйте собрать этот проект. Для его сборки необходимо явно указать цель, т.е. дать команду make hello.
После- измените любой из исходных файлов и соберите его снова. Обратите внимание на то, что во время второй компиляции, транслироваться будет только измененный файл.
После запуска make попытается сразу получить цель hello, но для ее создания необходимы файлы main.o и hello.o, которых пока еще нет. Поэтому выполнение правила будет отложено и make станет искать правила, описывающие получение недостающих реквизитов. Как только все реквизиты будут получены, make вернется к выполнению отложенной цели. Отсюда следует, что make выполняет правила рекурсивно.
Фиктивные цели
На самом деле, в качестве make целей могут выступать не только реальные файлы. Все, кому приходилось собирать программы из исходных кодов должны быть знакомы с двумя стандартными в мире UNIX командами:
Командой make производят компиляцию программы, командой make install — установку. Такой подход весьма удобен, поскольку все необходимое для сборки и развертывания приложения в целевой системе включено в один файл (забудем на время о скрипте configure). Обратите внимание на то, что в первом случае мы не указываем цель, а во втором целью является вовсе не создание файла install, а процесс установки приложения в систему. Проделывать такие фокусы нам позволяют так называемые фиктивные (phony) цели. Вот краткий список стандартных целей:
- all — является стандартной целью по умолчанию. При вызове make ее можно явно не указывать.
- clean — очистить каталог от всех файлов полученных в результате компиляции.
- install — произвести инсталляцию
- uninstall — и деинсталляцию соответственно.
Для того чтобы make не искал файлы с такими именами, их следует определить в Makefile, при помощи директивы .PHONY. Далее показан пример Makefile с целями all, clean, install и uninstall:
Теперь мы можем собрать нашу программу, произвести ее инсталлцию/деинсталляцию, а так же очистить рабочий каталог, используя для этого стандартные make цели.
Обратите внимание на то, что в цели all не указаны команды; все что ей нужно — получить реквизит hello. Зная о рекурсивной природе make, не сложно предположить как будет работать этот скрипт. Так же следует обратить особое внимание на то, что если файл hello уже имеется (остался после предыдущей компиляции) и его реквизиты не были изменены, то команда make ничего не станет пересобирать. Это классические грабли make. Так например, изменив заголовочный файл, случайно не включенный в список реквизитов, можно получить долгие часы головной боли. Поэтому, чтобы гарантированно полностью пересобрать проект, нужно предварительно очистить рабочий каталог:
Для выполнения целей install/uninstall вам потребуются использовать sudo.
Переменные
Все те, кто знакомы с правилом DRY (Don’t repeat yourself), наверняка уже заметили неладное, а именно — наш Makefile содержит большое число повторяющихся фрагментов, что может привести к путанице при последующих попытках его расширить или изменить. В императивных языках для этих целей у нас имеются переменные и константы; make тоже располагает подобными средствами. Переменные в make представляют собой именованные строки и определяются очень просто:
Существует негласное правило, согласно которому следует именовать переменные в верхнем регистре, например:
Так мы определили список исходных файлов. Для использования значения переменной ее следует разименовать при помощи конструкции $( ); например так:
Ниже представлен мэйкфайл, использующий две переменные: TARGET — для определения имени целевой программы и PREFIX — для определения пути установки программы в систему.
Это уже посимпатичней. Думаю, теперь вышеприведенный пример для вас в особых комментариях не нуждается.
Автоматические переменные
Автоматические переменные предназначены для упрощения мейкфайлов, но на мой взгляд негативно сказываются на их читабельности. Как бы то ни было, я приведу здесь несколько наиболее часто используемых переменных, а что с ними делать (и делать ли вообще) решать вам:
Источник