make install linux что делает
Заметки Дебианщика
debian, linux, php, mongo, oracle, bash
Чарующая магия configure, make и make install
Это небольшая заметка для начинающих линуксоидов, о том что же означают эти три замечательные команды и для чего одни нужны. Начнём, как говорится, с начала. Большинство программ перед использованием надо скомпилировать, то есть преобразовать из текста понятного человеку в набор единиц и нулей, понятных компьютеру. Процесс условно разделён на три этапа: конфигурирование (configure), сборка (make) и установка (make install). Подробности под катом 🙂
./configure
Выполнить настройку параметров конфигуратора можно при помощи ключей и аргументов этих самых ключей, например:
При помощи ключа —prefix=
Вы можете указать директорию, которая в дальнейшем будет выступать как префикс для вашей программы (то есть корневая директория). Это связанно с тем что в мире Linux и не только, существует специальная Иерархия Файловой Системы (HFS) в соответствии с которой любая программа, чтобы работать без ошибок, должна быть собрана и установлена.
В файловой системе есть три основных префикса, относительно которых большинство программ конфигурируется, а именно:
Если открыть любую из этих директорий, то можно увидеть очень схожую структуру, как минимум там будут папки: bin, etc, include, libs, sbin.
Если запустить ./configure без ключей, то префиксом по умолчанию (директория, в которую будет установлена собираемая программа) будет /usr/local, помните это если не можете запустить свою программу, возможно у Вас не прописан путь в PATH.
Кроме ключа —prefix в конфигураторе, как правило, имеется ещё множество других ключей, посмотреть их все можно если выполнить:
Самая важная и простая команда/программа, выполняет запуск процедуры компиляции приложения из исходного кода. Для своей работы данная программа использует специальные файлы Makefiles, в которых подробно описан процесс сборки приложения со всеми параметрами, которые мы указали конфигуратору. Результатом успешного выполнения команды make будет собранная программа в текущей директории.
make install
Данная команда выполняет непосредственную установку приложения в указанную, на этапе конфигурирования, директорию, после выполнения команды make install вы можете запустить свежеустановленную программу.
Послесловие
Чтобы не писать три команды по очереди можно написать их в одну строку:
./configure && make && make install
На самом деле make install так же может выполнить сборку, потому как задача install зависит от задачи all (то есть непосредственно сборки приложения), это означает что этап make можно пропустить и выполнить всего две команды, если записать их в одну строку получится:
./configure && make install
Удачи Вам! И спасибо за то что дочитали!
2 thoughts on “ Чарующая магия configure, make и make install ”
Всё, что нужно знать про эти три команды, так это то, что это отличный способ запомоить систему.
Спасибо огромное за статью,всё чётко и понятно.
Хочется взять и расстрелять, или ликбез о том, почему не стоит использовать make install
К написанию сей заметки меня сподвигло то, что я устал делать развёрнутые замечания на эту тему в комментариях к статьям, где в качестве части инструкции по сборке и настройке чего-либо для конкретного дистра предлагают выполнить make install. |
Суть сводится к тому, что эту команду в виде «make install» или «sudo make install» использовать в современных дистрибутивах нельзя.
Но ведь авторы программ в руководствах по установке пишут, что нужно использовать эту команду, возможно, скажете вы. Да, пишут. Но это лишь означает, что они не знают, какой у вас дистрибутив, и дистрибутив ли это вообще, может, вы вступили в секту и обкурилисьчитались LFS и теперь решили под свою хтоническую систему скомпилять их творение. А make install является универсальным, хоть и зачастую неправильным способом это сделать.
Лирическое отступление
Как известно, для нормальной работы большинство софта должно быть не только скомпилировано, но и правильно установлено в системе. Программы ожидают найти нужные им файлы в определённых местах, и места эти в большинстве *nix-систем зашиты в код на этапе компиляции. Помимо этого аспекта основным отличием процесса установки в linux/freebsd/whatever от таковой в Windows и MacOS является то, что программа не просто складывает кучу файлов в отдельную директорию в Program Files или /Applications, а «размазывает» себя по всей файловой системе. Библиотеки идут в lib, исполняемые файлы в bin, конфиги в etc, разного рода данные в var и так далее. Если вам вдруг понадобится её обновить, то всё это надо сначала как-то вычистить, т. к. при использовании новой версии остатки файлов от старой могут привести к совершенно непредсказуемым последствиям, зачастую нехорошим. Вероятность этого события не так велика, но оно вам надо на боевом сервере?
И что с того?
Так вот, если вы делали установку напрямую через make install, то нормально удалить или обновить софтину вы, скорее всего, не сможете. Более того, установка новой версии поверх старой, скорее всего, затрёт ваши изменения в конфигах. make install делает ровно то, что ему сказано — производит установку файлов в нужные места, игнорируя тот факт, что там что-то уже есть. После этого процесса совершенно никакой информации о том, что и куда ставилось, получить в удобоваримом виде невозможно. Иногда, конечно, Makefile поддерживает действие uninstall, но это встречается не так часто, да и не факт, что корректно работает. Помимо этого хранить для деинсталяции распакованное дерево исходников и правил сборки как-то странно.
Как бороться?
Поскольку в дистрибутивах пакеты имеют свойство иногда всё-таки обновляться, для решения этой проблемы придумали такую штуку как пакетный менеджер. При его использовании установка происходит примерно так:
В этом случае при обновлении можно безболезненно поудалять лишнее, а заодно посмотреть, не поменялись ли в системе файлы, помеченные как конфигурационные и спросить, что делать, если в новой версии их содержимое отличается. Помимо этого, пакетный менеджер не даст затереть файлы одного пакета при установке другого. В общем, много полезных штук он может сделать.
Если вы по незнанию/лени скопипастили make install из инструкции, то в системе появляются файлы, о которых пакетный менеджер не знает. Со всеми вытекающими, если вам мало того, что было перечислено ранее.
Что делать?
Так что надо собирать пакет.
У меня нет времени, чтобы ***ться с этим, лучше ещё раз сделаю make install, всё просто и понятно!
Спокойно, спокойно. Он у нас за ноги привязан. Всё не так уж страшно и сложно, как кажется на первый взгляд.
checkinstall
Данная чудесная утилита, будучи запущенной вместо make install задаст несколько вопросов, после чего сама соберёт и установит пакет. Всё, при обновлении никаких проблем с вычисткой старого хлама у вас не будет.
Сборка deb-пакета вручную
После чего получаем в свежесозданной директории весь тот набор файлов. Кстати, мы сейчас находимся в fakeroot-окружении, т. е. можно невозбранно менять владельца и права доступа файлов, но физически в системе владельцем останетесь вы сами. Софт же внутри fakeroot-сессии будет получать изменённую информацию, что позволит упаковать в архив файлы с корректными правами.
Далее создадим в «корне пакета» директорию DEBIAN и сложим в DEBIAN/conffiles список всех файлов, которые должны попасть в /etc:
После чего создаём файл DEBIAN/control следующего содержания:
При необходимости там же можно создать скрипты preinst, postinst, prerm и postrm.
«Правильный» процесс с предварительным созданием пакета исходного кода выходит за рамки данной заметки, а потому описан не будет, но для ваших целей оно обычно и не нужно.
Заключение
Как видите, тут нет абсолютно ничего сложного, но выполнение этих действий избавит вас от огромного числа проблем в будущем.
А авторам статей на хабре просьба: пишите checkinstall вместо make install. Не надо давать вредные советы.
Просто о make
Меня всегда привлекал минимализм. Идея о том, что одна вещь должна выполнять одну функцию, но при этом выполнять ее как можно лучше, вылилась в создание UNIX. И хотя UNIX давно уже нельзя назвать простой системой, да и минимализм в ней узреть не так то просто, ее можно считать наглядным примером количество- качественной трансформации множества простых и понятных вещей в одну весьма непростую и не прозрачную. В своем развитии make прошел примерно такой же путь: простота и ясность, с ростом масштабов, превратилась в жуткого монстра (вспомните свои ощущения, когда впервые открыли мэйкфайл).
Мое упорное игнорирование make в течении долгого времени, было обусловлено удобством используемых IDE, и нежеланием разбираться в этом ‘пережитке прошлого’ (по сути — ленью). Однако, все эти надоедливые кнопочки, менюшки ит.п. атрибуты всевозможных студий, заставили меня искать альтернативу тому методу работы, который я практиковал до сих пор. Нет, я не стал гуру make, но полученных мною знаний вполне достаточно для моих небольших проектов. Данная статья предназначена для тех, кто так же как и я еще совсем недавно, желают вырваться из уютного оконного рабства в аскетичный, но свободный мир шелла.
Make- основные сведения
make — утилита предназначенная для автоматизации преобразования файлов из одной формы в другую. Правила преобразования задаются в скрипте с именем Makefile, который должен находиться в корне рабочей директории проекта. Сам скрипт состоит из набора правил, которые в свою очередь описываются:
1) целями (то, что данное правило делает);
2) реквизитами (то, что необходимо для выполнения правила и получения целей);
3) командами (выполняющими данные преобразования).
В общем виде синтаксис makefile можно представить так:
То есть, правило make это ответы на три вопроса:
Несложно заметить что процессы трансляции и компиляции очень красиво ложатся на эту схему:
Простейший Makefile
Предположим, у нас имеется программа, состоящая всего из одного файла:
Для его компиляции достаточно очень простого мэйкфайла:
Компиляция из множества исходников
Предположим, что у нас имеется программа, состоящая из 2 файлов:
main.c
Makefile, выполняющий компиляцию этой программы может выглядеть так:
Он вполне работоспособен, однако имеет один значительный недостаток: какой — раскроем далее.
Инкрементная компиляция
Представим, что наша программа состоит из десятка- другого исходных файлов. Мы вносим изменения в один из них, и хотим ее пересобрать. Использование подхода описанного в предыдущем примере приведет к тому, что все без исключения исходные файлы будут снова скомпилированы, что негативно скажется на времени перекомпиляции. Решение — разделить компиляцию на два этапа: этап трансляции и этап линковки.
Теперь, после изменения одного из исходных файлов, достаточно произвести его трансляцию и линковку всех объектных файлов. При этом мы пропускаем этап трансляции не затронутых изменениями реквизитов, что сокращает время компиляции в целом. Такой подход называется инкрементной компиляцией. Для ее поддержки make сопоставляет время изменения целей и их реквизитов (используя данные файловой системы), благодаря чему самостоятельно решает какие правила следует выполнить, а какие можно просто проигнорировать:
Попробуйте собрать этот проект. Для его сборки необходимо явно указать цель, т.е. дать команду make hello.
После- измените любой из исходных файлов и соберите его снова. Обратите внимание на то, что во время второй компиляции, транслироваться будет только измененный файл.
После запуска make попытается сразу получить цель hello, но для ее создания необходимы файлы main.o и hello.o, которых пока еще нет. Поэтому выполнение правила будет отложено и make станет искать правила, описывающие получение недостающих реквизитов. Как только все реквизиты будут получены, make вернется к выполнению отложенной цели. Отсюда следует, что make выполняет правила рекурсивно.
Фиктивные цели
На самом деле, в качестве make целей могут выступать не только реальные файлы. Все, кому приходилось собирать программы из исходных кодов должны быть знакомы с двумя стандартными в мире UNIX командами:
Командой make производят компиляцию программы, командой make install — установку. Такой подход весьма удобен, поскольку все необходимое для сборки и развертывания приложения в целевой системе включено в один файл (забудем на время о скрипте configure). Обратите внимание на то, что в первом случае мы не указываем цель, а во втором целью является вовсе не создание файла install, а процесс установки приложения в систему. Проделывать такие фокусы нам позволяют так называемые фиктивные (phony) цели. Вот краткий список стандартных целей:
Теперь мы можем собрать нашу программу, произвести ее инсталлцию/деинсталляцию, а так же очистить рабочий каталог, используя для этого стандартные make цели.
Обратите внимание на то, что в цели all не указаны команды; все что ей нужно — получить реквизит hello. Зная о рекурсивной природе make, не сложно предположить как будет работать этот скрипт. Так же следует обратить особое внимание на то, что если файл hello уже имеется (остался после предыдущей компиляции) и его реквизиты не были изменены, то команда make ничего не станет пересобирать. Это классические грабли make. Так например, изменив заголовочный файл, случайно не включенный в список реквизитов, можно получить долгие часы головной боли. Поэтому, чтобы гарантированно полностью пересобрать проект, нужно предварительно очистить рабочий каталог:
Для выполнения целей install/uninstall вам потребуются использовать sudo.
Переменные
Все те, кто знакомы с правилом DRY (Don’t repeat yourself), наверняка уже заметили неладное, а именно — наш Makefile содержит большое число повторяющихся фрагментов, что может привести к путанице при последующих попытках его расширить или изменить. В императивных языках для этих целей у нас имеются переменные и константы; make тоже располагает подобными средствами. Переменные в make представляют собой именованные строки и определяются очень просто:
Существует негласное правило, согласно которому следует именовать переменные в верхнем регистре, например:
Ниже представлен мэйкфайл, использующий две переменные: TARGET — для определения имени целевой программы и PREFIX — для определения пути установки программы в систему.
Это уже посимпатичней. Думаю, теперь вышеприведенный пример для вас в особых комментариях не нуждается.
Автоматические переменные
Автоматические переменные предназначены для упрощения мейкфайлов, но на мой взгляд негативно сказываются на их читабельности. Как бы то ни было, я приведу здесь несколько наиболее часто используемых переменных, а что с ними делать (и делать ли вообще) решать вам:
Configure Make Install
Перед установкой
Сначала Вам скорее всего нужно скачать архив с программой, которую Вы хотите установить.
Например, команда для скачивания python3.7:
Затем распаковать архив
И перейти в только что распакованную директорию
В этой директории скорее всего будет находиться скрипт configure
Configure
Бинари уходят в usr/bin
libraries в usr/lib
Проверяется наличие всего необходимого
Создается файл MakeFile
makefile нужны для того чтобы печатать меньше названий файлов и опций вручную.
С их помощью можно делать build только тех файлов, которые изменились.
Make это инструмент, который вызывает компиллятор. Можно указать тот компиллятор который нужен именно Вам.
С помощью инструкций в makefile можно указать какие именно файлы нужно заново компилировать.
В директории находятся три .cpp файла, два .h файла и три .o файла, оставшиеся от прошлой компиляции.
Все они нужны для проекта и не могут быть объединены в один файл.
Известно, что Example.cpp включает в себя файл Second.h и других зависимостей не имеет.
Мы хотим, чтобы при изменении самого Example.cpp либо его зависимости Second.h начиналась новая компиляция Example.cpp а затем новый Example.o линковался со старыми Second.o и Third.o
Для этого напишем Makefile aomake
Отступы нужно ставить табуляцией
Смотрим на последние две строки:
Выигрыш в этой ситуации заключается в том, что нам не нужно было перекомпилировать Second.cpp и Third.cpp мы просто перелинковали уже существующие Second.o Third.o с новым Example.o
Чтобы запустить этот файл нужно к команде make добавить опцию f и название файла
У файла Second.cpp две зависимости: Second.h и Third.h
У файла Third.cpp только одна зависимость: Third.h
Учтём эти зависимости в нашем aomake
Ещё одной полезной опцией является j
Более подробную информацию по Makefile вы можете найти в статье «makefile tutorial»
Install
Как создавать, собирать, устанавливать и использовать пакеты с программами и библиотеками для UNIX-подобных систем
Речь пойдёт о программах и библиотеках для UNIX-подобных систем, распространяемых в виде исходного кода (в том числе в виде тарболлов), написанных обычно на C и C++ (хотя этот же порядок работы может применяться к софту на любом языке). Многие вещи в этой статье написаны применительно конкретно к GNU/Linux, хотя многое из статьи может быть обобщено и на другие UNIX-подобные ОС.
Под словом «пакет» я понимаю в этой статье пакет с исходными текстами, причём не пакет конкретного дистрибутива GNU/Linux, а просто пакет, исходящий от оригинальных авторов софта (UPD от 2017-02-09: кроме тех случаев, где из контекста ясно, что слово «пакет» употреблено в другом смысле).
В этой статье я разберу следующие вопросы:
И ещё одно предупреждение. Я написал эту статью наскоро для одного человека. А после написания подумал, мол, раз уж написал, выложу уж на Хабр, чтоб не пропала. Поэтому в статье есть недочёты типа нечёткого структуирования статьи, фраз типа «не осуществляет сама инклудивание» и пр. Я это исправлять не буду. Может когда-нибудь в следующей жизни, когда руки дойдут. Выбор был между тем, чтобы публиковать так или не публиковать вовсе.
Итак, начнём мы с того, что создадим пакет с программой Hello, world. Для начала определимся с системой сборки.
Собственно, сама сборка пакета обычно осуществляется с помощью программы make (хотя это не единственный путь). Конфиг для make обычно лежит в файле под названием Makefile.
Есть несколько вариантов: просто использовать make либо использовать совместно с make некую высокоуровневую систему сборки (обычно autotools или cmake), которая будет, собственно, генерировать конфиги для make.
Мы в нашем примере будет использовать только make для простоты. Итак, создаём hello.c:
Внимание! Работает на GNU/Linux. Работа под macOS не гарантируется! Этот Makefile не является портируемым вообще на все UNIX-подобные системы! Подробнее будет дальше.
здесь означает символ табуляции.
Это далеко не единственный способ написать этот Makefile. Вообще, цель всей моей статьи — дать некую базу. Что ещё можно в этом Makefile изменить, вы можете потом узнать из других источников.
Итак, теперь давайте разбирать наш Makefile.
Для начала скажу следующее. Допустим, пользователь скачал пакет. Ему нужно сперва собрать его, т. е. получить бинарники в каталоге с самим пакетом (либо в случае out of tree build получить их в неком другом каталоге, что не меняет сути), а затем установить, т. е. скопировать полученные бинарники в место их окончательного хранения в системе.
То есть смотрите. Вы залогинены под юзером user. Ваш домашний каталог /home/user. Вы скачали пакет, распаковали его, скажем в /home/user/Desktop/foo. Далее вы его собрали. Собрали в этой же папке, /home/user/Desktop/foo. Либо, если речь идёт об out of tree build, вы создали ещё одну папку /home/user/Desktop/foo-build и собрали в ней. Теперь, после сборки вы решаете установить её в /usr/local. Вот тут уже вам нужны права root. Вы при помощи sudo устанавливаете эту программу в /usr/local.
Пара слов о размещении каталогов в системе. Разберу лишь некоторые каталоги. Более подробную информацию можно найти в Filesystem Hierarchy Standard (поддержан многими дистрибутивами GNU/Linux) и по команде «man 7 hier» в GNU/Linux и, возможно, других ОС. Во всяком случае я расскажу, как они были устроены, скажем, лет пять назад (т. е. где-то в 2012-м году), всякие новые веяния типа недавнего нововведения в Fedora «давайте-ка мы всё переместим в /usr» я рассматривать не буду.
То есть, например, вы устанавливаете пакет, указывая ему prefix /usr/local. Тогда бинарники пойдут в /usr/local/bin, бинарные файлы библиотек — в /usr/local/lib и так далее.
Теперь вернусь к разбору Makefile. PREFIX — это и есть тот prefix, про который я сейчас говорил. В качестве дефолтного префикса (пользователь сможет его переопределить) у нас указан /usr/local — хороший дефолтный выбор. Обычно его всегда указывают в качестве дефолтного префикса при создании пакетов (к сожалению, некоторые пакеты этого всё же не делают, дальше будет подробнее). Далее идёт CC. Это стандартное название для переменной make, в которую кладут компилятор, в данном случае cc. cc — это в свою очередь обычно используемая команда для запуска компилятора по умолчанию в данной системе. Это может быть gcc или clang. На некоторых системах команда cc может отсутствовать. CFLAGS — стандартное название для переменной с флагами компиляции.
Если просто набрать make, то будет выполнена та цель, которая идёт в Makefile первой. Обычная практика в том, чтобы называть её all. И такая цель обычно собирает весь проект, но ничего не устанавливает. Эта цель обычно «виртуальная», т. е. у нас нет файла под названием all. Т. к. наша задача собрать лишь один бинарник hello, то мы просто делаем all зависящим от hello. Далее идёт описание цели сборки hello. Его можно было в принципе разбить на два этапа: сборка hello.o из hello.c и сборка hello из hello.o. Я так делать не стал для простоты.
Что делает install? Это почти то же, что и cp. Точные отличия я и сам не знаю. Для установки программ нужно использовать install, а не cp.
Здесь я предполагаю, что у вас на системе установлен так называемый BSD install. В GNU/Linux’е он есть. В некоторых системах его может не быть. Может быть какой-нибудь другой install, который в этой ситуации не сработает. Именно это я имел в виду, когда сказал, что работа в разных ОС не гарантируется.
Здесь я не рассматривал DESTDIR, который, между прочим, крайне рекомендуется использовать в Makefile. Я даже не рассматривал цель clean.
Это создаст архив, внутри которого есть каталог hello-1.0, который содержит hello.c и Makefile. Таков способ распространения пакетов.
C++-вариант пакета. Исходник будет тем же, его нужно будет назвать hello.cpp. Makefile будет таким:
Обратите внимание, что стандартное название переменной для флагов к компилятору C++ — это CXXFLAGS, а не CPPFLAGS. CPPFLAGS же — это название переменной для флагов к препроцессору C.
Теперь разберём, как устанавливать пакеты из сорцов (любые, программы и библиотеки). Независимо от системы сборки. Этот алгоритм будет пригоден в том числе для тарболла, который мы создали только что. Допустим, что пакет, который нужно собрать, тоже называется hello.
Первый шаг: скачать и зайти в папку с сорцами. Тут два варианта: скачиваем из системы контроля версий (я разберу для примера git) или скачиваем тарболл.
Первый вариант. git. Делаем clone:
Теперь нужно собрать. Будем считать для простоты, что мы не будем делать out of tree build (если автор пакета требует out of tree build, там обычно будут написаны инструкции, как это сделать). А значит, собирать мы будем в этой же папке, где сорцы. Т. е. в этой папке, в которую мы сейчас сделали cd.
Дальнейшие действия зависят от системы сборки, выбранной в проекте. Но независимо от системы сборки мы в процессе сборки должны будем указать prefix. Причём обычно его нужно будет указать именно на этапе сборки, а не на этапе установки, т. к. часто prefix захардкоживается внутрь бинарника. А это значит, что после установки программы в определённое место её нельзя просто так взять и передвинуть.
Я дам здесь примерные инструкции, работающие в большинстве случаев. Точные инструкции вы увидите у автора проекта, там могут быть разные нюансы.
Обязательно указывайте prefix при сборке (что бы там не писал в инструкции автор). Если вы не укажите, то будет выбран дефолтный. Обычно это /usr/local, и это достаточно хороший выбор. А если нет? Что если автор пакета указал какой-то другой дефолтный префикс? Вы установите непонятно куда. В частности libqglviewer использует в качестве дефолтного префикса /usr, что совершенно неправильно (я отправил автору баг репорт). Итак, совершенно всегда указывайте префикс. Читайте инструкции, которые автор указывает на своём сайте и прикидывайте, куда впихнуть prefix.
Итак, какие могут быть системы сборки. Во-первых, может быть просто make. Такой вариант с голым make встречается редко. Один из немногих пакетов с «голым» make — bzip ( www.bzip.org ). В случае с нашим hello-1.0.tar.xz, который мы создали, у нас именно такой вариант.
Итак, собирать в случае голого make нужно так:
(Конкретно в случае с bzip на этапе сборки указывать PREFIX не надо. Но теоретически можно представить себе пакет, который захардкоживает PREFIX внутрь бинарника. Поэтому в общем случае PREFIX нужен.)
Следующий вариант — это autotools. В этом случае собираем так:
Следующий вариант — cmake. Собираем так (обратите внимание на точку в конце команды cmake):
Откуда точка в конце? Дело в том, что cmake’у нужно передавать путь к сорцам. А поскольку у нас не out of tree build, мы собираем здесь же. Сорцы находятся там же, где находимся мы. Поэтому точка, т. е. текущий каталог.
Итак, собрали одним из этих способов. Что дальше? Теперь нужно установить.
В случае голого make это делается так:
Нужно будет указать тот же prefix, который вы указывали при сборке.
В случае autotools и cmake так:
В случае, если для записи в prefix вам нужен sudo, то вот эту команду для установки нужно будет набирать с sudo. Вообще, сборка всегда осуществляется с обычными правами, а вот установка осуществляется с теми правами, которые нужны, чтобы записать в prefix.
В результате бинарник положился в /foo/bin.
Теперь хочу ещё немного поговорить про префиксы. Какие префиксы вообще есть?
Префикс /. Вряд ли когда-нибудь вам придётся его выбирать. Он используется для программ, критичных для ранних стадий загрузки ОС (т. е. критичные элементы для загрузки находятся в /bin, /lib и т. д.) (впрочем, даже если вам нужно установить программу в /, её сперва устанавливают в /usr, т. е. собирают и устанавливают с префиксом /usr, а потом перемещают необходимое в / [т. е. перемещают из /usr/bin в /bin, скажем], во всяком случае именно так поступают авторы Linux From Scratch 7.10 с пакетом, скажем, bash).
Префикс /usr. Стандартный префикс, используемый обычно для программ, установленных через менеджер пакетов. То есть если вы установили программу через менеджер пакетов, она ведёт себя так, словно она собрана и установлена на вашей системе с префиксом /usr. Самому устанавливать пакеты с префиксом /usr нельзя.
Префикс /usr/local. Отличный префикс для установки туда программ самостоятельно. Хорош тем, что /usr/local/bin есть в дефолтном PATH (во всяком случае в дебиане). То есть сразу после установки программы вы сможете просто запускать программу по названию. Потому что бинарник лежит в /usr/local/bin, а /usr/local/bin есть в PATH. Плох тем, что там все программы лежат смешанно. Вот допустим, вы установили библиотеку foo, а потом библиотеку bar. Обе в этот prefix. Тогда дерево может выглядеть так (в совсем упрощённом виде):
Видите? Всё смешано. Нет единой папки, которая бы содержала «всё, связанное с foo» и другой папки, которая бы содержала «всё, связанное с bar». (Хотя это ваше дело, считать, что это действительно плохо или нет). Понятное дело, что такая же проблема присутствует при любой установке разных пакетов в один префикс. То есть префикс /usr страдает от того же: пакеты «размазаны» по системе (здесь уже речь идёт о пакетах, поставленных через менеджер пакетов, т. е. тех, которые, собственно, составляют систему). Собственно, это и есть одно из бросающихся отличий большинства UNIX-подобных систем от Windows. В Windows каждая программа находится в своей папке в Program Files. В большинстве UNIX-подобных систем она «размазана» по системе. (UPD от 2017-02-09: в Windows программы на самом деле тоже «размазаны», скажем, по реестру, просто это не так бросается в глаза.) Существуют дистибутивы GNU/Linux, «решающие» эту проблему, например, GoboLinux. Там каждый пакет в своём каталоге, как в Windows.
Префиксы вида /opt/XXX. Папку /opt предполагается использовать следующим образом: в ней нужно создавать подкаталоги, называть их названиями пакетов и использовать эти подкаталоги как префиксы. При таком подходе указанная выше проблема /usr/local (если считать её проблемой) исчезает. Каждый пакет будет установлен в свой каталог. Приведённый выше пример с foo и bar будет выглядеть так (я бы посоветовал в названии подкаталогов в /opt указывать ещё и номер версии):
Недостаток у такого решения тоже есть. Вам придётся самому добавлять все эти бесчисленные каталоги /opt/foo-1.0/bin (для каждого пакета) в PATH.
Префиксы, соответствующие домашним каталогам. Т. е., скажем, /home/user. Советую в случае, когда хочется поставить «только для себя», т. е. только для одного юзера. Или когда нет прав root. Возможно, ваши конфиги, поставляемые с ОС уже настроены таким образом, чтобы помещать
/bin в PATH при условии, что такой каталог есть. Так что PATH будет настроен как надо.
Каждый префикс может содержать в себе свои bin, sbin, lib, include и т. д.
Итак, что из этого выбрать? Если нужно поставить на всей системе, то я бы посоветовал /opt/XXX. Я сам так обычно ставлю.
Допустим, нужно собрать некий файл a.c с этой библиотекой. Как это сделать?
Во-первых, вверху файла нужно написать #include, соответствующий подключаему хедеру. Ну а собирать нужно так:
Давайте разбираться. Для начала скажу, что I (большая английская и) и l (маленькая английская эль) — это две разные буквы. Не перепутайте их в приведённых командах.
Первая команда производит компиляцию, то есть создаёт a.o на основе a.c. Вторая — линковку, то есть окончательный бинарник на основании a.o.
Можно соединить две наши команды в одну, тогда будет что-то такое:
Если вы установите у себя на машине libfoo и libfoo-dev, то результат будет как если бы вы сами собрали пакет foo из исходных кодов с префиксом /usr. У вас на системе будут, скажем, файлы: