Почему у make-файлов должна быть цель «установить»?

18

Исходя из мира C и C ++, большинство систем сборки имеют installцель, в частности Makefiles (где это рекомендуется GNU, например) или CMake . Эта цель копирует файлы времени выполнения (исполняемые файлы, библиотеки, ...) в операционной системе (например, в C:\Program Files\Windows).

Это выглядит очень странно, так как для меня сборка программ не является обязанностью системы сборки (на самом деле это ответственность операционной системы / менеджера пакетов). Это также означает, что система сборки или скрипт сборки должны знать организацию установленных программ с переменными среды, переменными реестра, символическими ссылками, разрешениями и т. Д.

В лучшем случае системы сборки должны иметь releaseцель, которая будет выводить устанавливаемую программу (например, .debили .msi), а затем просить операционную систему установить эту программу. Это также позволит пользователю удалить без необходимости печатать make uninstall.

Итак, мой вопрос: почему система сборки обычно рекомендует иметь installцель?

Synxis
источник
7
Ваше утверждение о том, что «make install» не входит в сферу ответственности системы сборки, но гораздо более сложная и специфичная для платформы ответственность за создание устанавливаемого пакета.
pmf
2
В любом случае: иногда вы хотите установить приложение, которое не обрабатывается менеджером ОС / пакетов (поскольку оно имеет зависимости, которые могут привести к конфликтам, которые невозможно разрешить с помощью менеджера пакетов и т. Д.). make installобычно устанавливается в /usr/local(или даже /opt) каталогах, которые не обрабатываются «базовой системой управления ОС / пакетами». Не знаю, есть ли в Windows какое-то подобное соглашение.
Бакуриу
11
«Это кажется действительно хакерским». Что вы ожидали от мира C / C ++? ;-)
Мейсон Уилер
1
Обратите внимание, что make installнет никакого смысла, когда мы говорим о кросс-компиляции
Хаген фон Айцен
1
@HagenvonEitzen это делает с DESTDIR.
Nax 'vi-vim-nvim'

Ответы:

23

Многие сценарии сборки или файлы Makefile имеют цель установки, потому что они были созданы до того, как существовали менеджеры пакетов, и потому что даже сегодня многие системы не имеют менеджеров пакетов. Кроме того, существуют системы, где make installфактически является предпочтительным способом управления пакетами.

Йорг Миттаг
источник
Мне любопытно о системах, где make installпредпочтительнее. Кроме того, я имел в виду менеджер программ, когда говорил, что make-файлы должны создавать устанавливаемые пакеты. Я думаю, что почти все ОС имеют способ управления установленными программами? Например, в Windows нет диспетчера пакетов (кроме хранилища), но все еще есть способ управления установленными программами (с помощью .msiпакетов для примеров)
Synxis
2
@Synxis BSD, Linux, Unix все используют make-файлы. Я предпочитаю использовать их для установки, я не знаю, но у вас часто есть такая возможность make install.
Роб
1
В Debian, по крайней мере, предпочтительнее использовать checkinstallover make installпо двум причинам: «Вы можете легко удалить пакет за один шаг». и «Вы можете установить полученный пакет на нескольких машинах». - поскольку checkinstall собирает .deb и устанавливает его, он использует менеджер пакетов ...
Аарон Холл,
1
@Synxis - существует несколько дистрибутивов linux (часто называемых исходными дистрибутивами), в которых менеджер пакетов устанавливает программы, загружая файл tar, распаковывает его и запускаетmake install
slebetman
1
@AaronHall Поправьте меня, если я ошибаюсь, но у меня сложилось впечатление, что checkinstallвызов фактически использует make install и отслеживает свои действия для сборки пакета.
cmaster - восстановить монику
5

У A makefileможет не быть installцели, и, что более важно, у вас могут быть программы, которые даже не должны устанавливаться (например, потому что они должны запускаться из своего каталога сборки или потому, что они могут запускаться в любом месте). installЦель просто условность для обычных makefile-s.

Однако для многих программ требуются внешние ресурсы (например, шрифты, базы данных, файлы конфигурации и т. Д.). И их исполняемые файлы часто выдвигают некоторую гипотезу об этих ресурсах. Например, ваша bashоболочка обычно читает какой-то файл инициализации из /etc/bash.bashrcetc ... Эти ресурсы обычно находятся в файловой системе (см. Hier (7) для соглашений об иерархии файлов), а путь к файлу по умолчанию встроен в ваш исполняемый файл.

Попробуйте использовать strings (1) в большинстве исполняемых файлов вашей системы. Вы узнаете, какие пути к файлам ему известны.

Кстати, для многих программ GNU autoconf, вы можете работать make install DESTDIR=/tmp/destdir/без прав root. Затем /tmp/destdir/заполняется файлами, которые должны быть позже упакованы.

FWIW, я склонен полагать, что моя программа bismon (GPLv3 + лицензированная) (описанная в моем отчете bismon-chariot-doc.pdf ) не может быть «установлена»; Я не уверен, что смогу доказать это, и я не могу себе представить, как я могу сделать эту программу устанавливаемой.

Василий Старынкевич
источник
2
DESTDIR или другие префиксы слишком часто забываются. Как только задействуются внешние ресурсы, такие как динамические библиотеки, невозможно создать программное обеспечение, не зная, где оно будет установлено . Также отлично подходит для установки в нестандартных местах, например /optили в $HOME. Единственный способ избежать разных префиксов - это использовать контейнеры, но это, конечно, решение для Linux.
Амон
2
Я видел более одного пакета, который, если вы попробуете DESTDIR = / tmp / destdir, не будет работать позже при установке в обычное место, потому что DESTDIR использовался при генерации пути.
Джошуа
@amon: я не уверен, что охарактеризовал бы контейнеры как специфичные для Linux. Linux может быть общей целевой платформой для контейнеризации, но некоторая форма контейнерной технологии существует в большинстве современных операционных систем.
Кевин
1
@ Joshua Не должно быть, DESTDIR должен быть релевантным только на этапе установки. Вы должны быть в состоянии сделать: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install и иметь возможность перемещать пакет /opt/fooбез каких-либо проблем.
Nax 'vi-vim-nvim'
3

Есть несколько причин, которые приходят на ум.

  • Многие программы для создания пакетов - например, система сборки Debian и RPM IIRC - уже ожидают, что скрипт сборки "установит" программу в какой-то специальный подкаталог. Так что это обусловлено обратной совместимостью в обоих направлениях.
  • Пользователь может захотеть установить программное обеспечение в локальное пространство, например, в $HOMEкаталог. Не все менеджеры пакетов поддерживают это.
  • Могут быть среды, в которых нет пакетов.
max630
источник
Я немного перефразировал вопрос, я имел в виду менеджер программ, когда сказал, что make-файлы должны создавать устанавливаемые пакеты.
Synxis
1

Одна из причин, не упомянутых, заключается в том, что вы часто не используете текущую версию программного обеспечения или измененную версию программного обеспечения. Попытка создать собственный пакет - это не только дополнительная работа, но и конфликт с созданными и распространяемыми пакетами. В открытом исходном коде это часто случается, особенно если в будущих версиях, которые вы используете, вносятся критические изменения.

Допустим, вы используете проект FOO с открытым исходным кодом, который в настоящее время находится на версии 2.0.1, и вы используете версию 1.3.0. Вы не хотите использовать что-либо выше этого, потому что версия 2.0.0 несовместима с тем, что вы делаете в настоящее время, но в 2.0.1 есть единственное исправление, которое вам крайне необходимо. Имея make installопцию, вы можете установить модифицированное программное обеспечение 1.3.0, не беспокоясь о создании пакета и его установке в вашей системе.

Дом
источник
1

Обычно дистрибутивы Linux отделяют обслуживание программы от обслуживания пакета. Система сборки, которая объединяет создание пакетов, вынуждает сопровождающих программ также выполнять обслуживание пакетов.

Обычно это плохая идея. В дистрибутивах имеется много инфраструктуры для проверки внутренней согласованности, обеспечения двоичных файлов для нескольких целевых платформ, внесения небольших изменений для лучшей интеграции с остальной частью системы и обеспечения согласованности действий для пользователей, сообщающих об ошибках.

Чтобы сгенерировать пакеты непосредственно из системы сборки, вам придется либо интегрировать, либо обойти всю эту инфраструктуру. Интеграция будет большой работой для сомнительной выгоды, а обход ее даст худший пользовательский опыт.

Это одна из проблем «верхней части пищевой цепи», которая характерна для многопартийных систем. Если у вас несколько сложных систем, должна быть четкая иерархия того, какая система отвечает за координацию всех остальных.

В случае управления установкой программного обеспечения этим компонентом является менеджер пакетов, который будет запускать систему сборки пакета, а затем принимать вывод через удобный интерфейс («файлы в каталоге после этапа установки»), генерировать пакет и подготавливать его. это для загрузки в хранилище.

Менеджер пакетов находится здесь между системой сборки и репозиторием и находится в лучшем положении, чтобы хорошо интегрироваться с обоими.

Вы, возможно, заметили, что есть только несколько пакетов JavaScript, доступных через, npmтакже доступных через apt- это главным образом потому, что люди JavaScript решили это, npmи связанный репозиторий должен был стать вершиной их пищевой цепи, что сделало его почти невозможным отправляйте эти пакеты как пакеты Debian.

С моей шляпой разработчика Debian: если вы выпускаете программное обеспечение с открытым исходным кодом, пожалуйста, оставьте упаковку сопровождающим. Это экономит вам и нам много работы.

Саймон Рихтер
источник
Вы ничего не сказали о том, почему существует цель установки, и мне кажется, что большая часть того, что вы написали, применима и к ней ...
curiousdannii
1
@curiousdannii, должен быть какой-то интерфейс между системой сборки и менеджером пакетов, и это оказывается самым простым, поэтому он победил.
Саймон Рихтер
1

Разработчики приложений знают, куда должен идти каждый файл. Они могут оставить это в документации, и сопровождающие пакета прочитают это и создадут скрипт для каждого пакета. Возможно, сопровождающие пакета неправильно интерпретируют документацию и должны будут отлаживать сценарий, пока он не заработает. Это неэффективно. Разработчику приложения лучше написать скрипт для правильной установки написанного им приложения.

Он мог написать скрипт установки с произвольным именем или, возможно, сделать его частью процедуры другого скрипта. Однако, имея стандартную команду установки make install(соглашение, предшествующее менеджерам пакетов), создавать пакеты стало действительно легко. Если вы посмотрите на шаблон PKGBUILD для создания пакетов Archlinux , то увидите, что функция, которая фактически упаковывает пакеты, просто выполняет make DESTDIR="$pkgdir/" install. Это, вероятно, работает для большинства пакетов и, возможно, с небольшой модификацией. Благодаря тому, что make(и автоинструменты) являются стандартными, упаковка действительно проста.

Йол
источник