Научиться компилировать вещи из исходного кода (в Unix / Linux / OSX)

47

Хотя я устанавливаю программное обеспечение из пакетов (MacPorts / apt-get) везде, где это возможно, мне часто приходится собирать пакеты из исходного кода. ./configure && make && sudo make installобычно достаточно, но иногда это не работает - и когда это не так, я часто зацикливаюсь. Это почти всегда так или иначе относится к другим библиотечным зависимостям.

Я хотел бы узнать следующее:

  • Как я могу выяснить, какие аргументы передать ./configure?
  • Как общие библиотеки работают в OS X / Linux - где они живут в файловой системе, как ./configure && makeих находят, что на самом деле происходит, когда они связаны с
  • Каковы фактические различия между разделяемой и статически связанной библиотекой? Почему я не могу просто статически связать все (оперативная память и дисковое пространство дешевы в наши дни) и, следовательно, избежать странных конфликтов версий библиотеки?
  • Как узнать, какие библиотеки у меня установлены и какие версии?
  • Как я могу установить более одной версии библиотеки, не нарушая мою обычную систему?
  • Если я буду устанавливать вещи из источника в системе, в противном случае управляются с помощью пакетов, что самый чистый способ сделать это?
  • Предполагая, что мне удается скомпилировать что-то из исходного кода, как я могу затем упаковать это, чтобы другим людям не приходилось прыгать через те же обручи? Особенно на OS X ....
  • Какие инструменты командной строки мне нужно освоить, чтобы хорошо разбираться в этом? Такие вещи, как otool, pkg-config и т. Д.

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

Саймон Уиллисон
источник

Ответы:

40

Я прошу прощения за прямой ответ на все вопросы, но я не знаю каких-либо полезных руководств, часто задаваемых вопросов и т. Д. В основном следует 8 лет создания настольных приложений (которые я помогаю распространять), разочарование и поиск в Google:

1. Как мне определить, какие аргументы передать ./configure?

Практика действительно. Автоинструментальные средства достаточно просты, так как они последовательны. Но есть много вещей, использующих cmake или пользовательские сценарии сборки. Как правило, вам не нужно ничего передавать для настройки, нужно выяснить, может ли ваша система собрать foo-tool или нет.

Инструменты настройки и GNU все ищут в /, / usr и / usr / local для зависимостей. Если вы устанавливаете что-либо где-либо еще (что усложняет ситуацию, если зависимость была установлена ​​MacPorts или Fink), вам придется передать флаг, чтобы сконфигурировать или изменить среду оболочки, чтобы инструменты GNU могли найти эти зависимости.

2. Как разделяемые библиотеки работают в OS X / Linux - где они находятся в файловой системе, как ./configure && make находит их, что на самом деле происходит, когда они связаны с

В Linux их необходимо установить по пути, который может найти динамический компоновщик, это определяется LD_LIBRARY_PATHпеременной среды и содержимым /etc/ld.conf. На Mac это то же самое для большинства программного обеспечения с открытым исходным кодом почти всегда (если это не проект Xcode). За исключением переменной env DYLD_LIBRARY_PATH.

Существует путь по умолчанию, по которому компоновщик ищет библиотеки. Это / lib: / usr / lib: / usr / local / lib

Вы можете дополнить это, используя переменную CPATH, или CFLAGS, или любое другое число переменных среды (действительно сложно). Я предлагаю CFLAGS так:

export CFLAGS = "$ CFLAGS -L / new / path"

Параметр -L добавляет к пути ссылки.

Современные вещи используют инструмент pkg-config. Современные вещи, которые вы устанавливаете, также устанавливают файл .pc, который описывает библиотеку, где она находится и как на нее ссылаться. Это может облегчить жизнь. Но он не поставляется с OS X 10.5, поэтому вам придется установить его тоже. Также многие базовые отделы не поддерживают это.

Акт связывания просто «разрешает эту функцию во время выполнения», на самом деле это большая таблица строк.

3. Каковы фактические различия между разделяемой и статически связанной библиотекой? Почему я не могу просто статически связать все (оперативная память и дисковое пространство дешевы в наши дни) и, следовательно, избежать странных конфликтов версий библиотеки?

Когда вы ссылаетесь на файл статической библиотеки, код становится частью вашего приложения. Было бы так, как если бы для этой библиотеки был один гигантский файл .c, и вы скомпилировали его в свое приложение.

Динамические библиотеки имеют один и тот же код, но при запуске приложения код загружается в приложение во время выполнения (упрощенное объяснение).

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

Хитрость заключается в том, чтобы изменить строку ссылки с -lfoo на -l / path / на / static / foo.a

Вы, вероятно, можете найти и заменить. После этого проверьте, что инструмент не ссылается на .so или dylib, используя ldd foo или otool -L foo

Еще одна проблема - не все библиотеки компилируются в статические библиотеки. Многие делают. Но тогда MacPorts или Debian, возможно, решили не поставлять его.

4. Как я могу узнать, какие библиотеки я установил и какие версии?

Если у вас есть файлы pkg-config для этих библиотек, это легко:

pkg-config --list-all

В противном случае вы часто не можете легко. У dylib может быть soname (т. Е. Foo.0.1.dylib, soname равен 0.1), который совпадает с версией библиотеки. Однако это не обязательно. Soname - это бинарная функция вычислимости, вам нужно увеличить основную часть soname, если вы измените формат функций в библиотеке. Таким образом, вы можете получить, например. версия 14.0.5 soname для библиотеки 2.0. Хотя это не распространено.

Я разочаровался в подобных вещах и разработал решение для этого на Mac, и я буду говорить об этом позже.

5. Как я могу установить более одной версии библиотеки, не нарушая мою обычную систему?

Мое решение этого здесь: http://github.com/mxcl/homebrew/

Мне нравится установка из исходных текстов, и мне нужен инструмент, который бы упростил его, но с некоторым управлением пакетами. Так что с Homebrew я строю, например. wget себя из исходного кода, но не забудьте установить специальный префикс:

/usr/local/Cellar/wget/1.1.4

Затем я использую инструмент homebrew для символической ссылки всего этого в / usr / local, поэтому у меня все еще есть / usr / local / bin / wget и /usr/local/lib/libwget.dylib

Позже, если мне понадобится другая версия wget, я могу установить ее параллельно и просто изменить версию, связанную с деревом / usr / local.

6. Если я устанавливаю материал из источника в систему, которая в противном случае управляется с помощью пакетов, каков самый чистый способ сделать это?

Я считаю, что путь Homebrew является самым чистым, поэтому используйте его или сделайте эквивалент. Установите в / usr / local / pkgs / name / version и оставьте символическую ссылку или жесткую ссылку в остальных.

Используйте / usr / local. Каждый существующий инструмент сборки ищет там зависимости и заголовки. Ваша жизнь будет намного проще.

7. Предполагая, что мне удастся скомпилировать что-то из исходного кода, как я могу затем упаковать это, чтобы другим людям не приходилось прыгать через те же обручи? Особенно на OS X ....

Если у него нет зависимостей, вы можете заархивировать каталог сборки и передать его кому-то еще, кто затем сможет выполнить «make install». Однако вы можете сделать это надежно только для точно таких же версий OS X. В Linux это, вероятно, будет работать для аналогичного Linux (например, Ubuntu) с той же версией ядра и младшей версией libc.

Причина, по которой нелегко распространять двоичные файлы в Unix, заключается в двоичной совместимости. Люди GNU и все остальные часто меняют свои двоичные интерфейсы.

По сути, не распространяйте двоичные файлы. Вещи, вероятно, сломаются очень странными способами.

На Mac лучший вариант - сделать пакет для macports. Все используют макпорты. В Linux так много разных систем сборки и комбинаций, я не думаю, что есть лучший совет, чем написать запись в блоге о том, как вам удалось собрать инструмент x в y странной конфигурации.

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

Одна из моих будущих целей с Homebrew - сделать так, чтобы можно было щелкнуть ссылку на веб-сайте (например, homebrew: // blah, и он загрузит скрипт Ruby, установит deps для этого пакета, а затем соберет приложение. Но да, еще не сделано, но не слишком сложно, учитывая дизайн, который я выбрал.

8. Какие инструменты командной строки мне нужно освоить, чтобы хорошо разбираться в этом? Такие вещи, как otool, pkg-config и т. Д.

otool действительно полезен только потом. Он говорит вам, на что ссылаются встроенные двоичные файлы. Когда вы выясняете зависимости инструмента, который вам нужно создать, он бесполезен. То же самое относится и к pkg-config, так как вы уже установили зависимость, прежде чем сможете ее использовать.

Моя цепочка инструментов: прочитайте файлы README и INSTALL и выполните настройку --help. Посмотрите выходные данные сборки, чтобы убедиться, что это нормально. Разобрать любые ошибки сборки. Возможно в будущем, спросите на serverfault :)

Макс Хауэлл
источник
2
Интересно, что Homebrew очень похож на Portage (менеджер пакетов из Gentoo Linux). Звучит как хорошая работа.
Дэвид З,
12

Это огромная тема, поэтому давайте начнем с общих библиотек в Linux (ELF в Linux и Mach-O в OS X). Ульрих Дреппер имеет хорошее введение в написание DSO (динамических общих объектов), в котором описывается некоторая история общих библиотек в Linux. здесь, в том числе, почему они важны

Ульрих также описывает, почему статическое связывание считается вредным. Одним из ключевых моментов здесь являются обновления безопасности. Переполнения буфера в общей библиотеке (например, zlib), которая статически связана статически, может вызвать огромные накладные расходы для дистрибутивов - это произошло с zlib 1.1.3 ( рекомендация Red Hat )

ELF

Ссылка на страницу руководства ld.so

man ld.so 

объясняет основные пути и файлы, связанные с динамическим связыванием во время выполнения. В современных системах Linux вы увидите дополнительные пути, добавленные через /etc/ld.so.conf.d/, добавленные обычно через глобус, включенный в /etc/ld.so.conf.

Если вы хотите увидеть, что доступно динамически через вашу конфигурацию ld.so, вы можете запустить

ldconfig -v -N -X

Чтение инструкций DSO должно дать вам хороший базовый уровень знаний, чтобы затем понять, как эти принципы применяются к Mach-O в OS X.

Мачо

На OS X двоичный формат - Mach-O. Локальная системная документация для компоновщика

man dyld

Документация формата Mach доступна от Apple

Инструменты сборки UNIX

Распространенная configure, make, make installпроцесс , как правило , обеспечивается GNU Autotools , который имеет онлайн - книгу , которая охватывает некоторые из истории Configure / раскола сборки и инструментарий , GNU. Autoconf использует тесты для определения доступности функций в целевой системе сборки, для этого используется язык макросов M4 . Automake - это, по сути, шаблонный метод для Makefile, причем этот шаблон обычно называется Makefile.am, который выводит Makefile.in, который выводится из autoconf (скрипт configure) и преобразуется в Makefile.

Программа GNU hello служит хорошим примером для понимания цепочки инструментов GNU - и руководство включает документацию по автоинструментам.


источник
10

Симон! Я знаю, что ты чувствуешь; Я тоже боролся с этой частью изучения Linux. Основываясь на своем собственном опыте, я написал учебник о некоторых элементах, к которым вы обращаетесь (в основном в качестве справки для себя!): Http://easyaspy.blogspot.com/2008/12/buildinginstall-application-from.html . Я думаю, вы оцените мою заметку о том, как простые приложения Python собирать / устанавливать. :)

Надеюсь, что это поможет! И счастливой компиляции.

Тим Джонс


Сборка / установка приложения из исходного кода в Ubuntu Linux

В то время как репозитории Ubuntu переполнены отличными приложениями, в тот или иной момент вы обязательно столкнетесь с этим «обязательным» инструментом, которого нет в репозиториях (или не имеет пакета Debian), или вам нужен более новая версия, чем в репозиториях. Чем ты занимаешься? Ну, вы должны собрать приложение из исходного кода! Не волнуйтесь, это действительно не так сложно, как кажется. Вот несколько советов, основанных на моем опыте перехода от уровня любителя! (Хотя я использую Ubuntu для этого примера, общие понятия должны быть применимы к большинству любых дистрибутивов Unix / Linux, таких как Fedora, и даже к платформе Cygwin в Windows.)

Основной процесс сборки (компиляции) большинства приложений из исходных текстов выполняется следующим образом: configure -> compile -> install. Типичные команды Unix / Linux для выполнения этих действий: config-> make-> make install. В некоторых случаях вы даже найдете веб-страницы, которые показывают, что все это можно объединить в одну команду:

$ config && make && make install

Конечно, эта команда предполагает, что нет никаких проблем ни на одном из этих шагов. Здесь начинается самое интересное!

Начиная

Если вы ранее не компилировали приложение из исходного кода в своей системе, вам, вероятно, потребуется настроить его с помощью некоторых общих инструментов разработки, таких как gccнабор компиляторов, некоторые распространенные заголовочные файлы (воспринимайте это как код, который уже был написан кем-то еще, который используется программой, которую вы устанавливаете), и инструментом make. К счастью, в Ubuntu есть метапакет, build-essentialкоторый будет устанавливать его. Чтобы установить его (или просто убедиться, что он у вас уже есть!), Запустите эту команду в терминале:

$ sudo apt-get install build-essential

Теперь, когда у вас есть базовая настройка, загрузите исходные файлы приложения и сохраните их в каталоге, для которого у вас есть разрешения на чтение / запись, например в «домашнем» каталоге. Как правило, они находятся в архивном файле с расширением либо либо, .tar.gzлибо .tar.bz2. Это .tarпросто означает, что это «ленточный архив», который представляет собой группу файлов, сохраняющую их относительную структуру каталогов. Это .gzозначает gzip (GNU zip), который является популярным форматом сжатия Unix / Linux. Точно так же .bz2расшифровывается как bzip2, который является более новым форматом сжатия, который обеспечивает более высокое сжатие (меньший размер сжатого файла), чем gzip.

После того, как вы загрузили исходный файл, откройте окно терминала (системный терминал из меню Ubuntu) и перейдите в каталог, в котором вы сохранили файл. (Я буду использовать ~/downloadв этом примере. Здесь '~' - это ярлык для вашей "домашней" директории.) Используйте команду tar, чтобы извлечь файлы из загруженного архивного файла:

Если ваш файл является архивом gzip (например, заканчивается на .tar.gz), используйте команду:

            $ tar -zxvf filename.tar.gz

Если ваш файл является архивом bzip2 (например, заканчивается на .tar.bz2), используйте команду:

            $ tar -jxvf filename.tar.gz

Совет: если вы не хотите запоминать все параметры командной строки для извлечения архивов, я рекомендую приобрести одну (или обе) из этих утилит: dtrx (моя любимая!) Или deco (более популярная). Используя любую из этих утилит, вы просто вводите название утилиты (dtrx или deco) и имя файла, оно делает все остальное. Оба они «знают», как обрабатывать большинство форматов архивов, с которыми вы, вероятно, столкнетесь, и у них отличная обработка ошибок.

При сборке из исходного кода вы можете столкнуться с двумя распространенными типами ошибок:

  1. Ошибки конфигурации возникают, когда вы запускаете скрипт конфигурации (обычно называемый config или configure), чтобы создать make-файл, соответствующий вашей установке.
  2. Ошибки компилятора возникают, когда вы запускаете команду make (после того, как был сгенерирован make-файл), и компилятор не может найти какой-то необходимый ему код.

Мы рассмотрим каждый из них и обсудим, как их решить.

Конфигурация и ошибки конфигурации

После того, как вы извлекли файл архива исходного кода, в терминале вы должны перейти в каталог, содержащий извлеченные файлы. Обычно это имя каталога совпадает с именем файла (без расширения .tar.gzили .tar.bz2). Однако иногда имя каталога - это просто имя приложения без какой-либо информации о версии.

В исходном каталоге найдите READMEфайл и / или INSTALLфайл (или что-то с похожими именами). Эти файлы обычно содержат полезную информацию о том, как собирать / компилировать приложение и устанавливать его, включая информацию о зависимостях. «Зависимости» - это просто причудливые названия для других компонентов или библиотек, которые необходимы для успешной компиляции.

После того, как вы прочитали файл READMEи / или INSTALL(и, надеюсь, просмотрели любую соответствующую онлайн-документацию по приложению), найдите исполняемый файл (для которого в файле установлено разрешение "x") с именем configили configure. Иногда файл может иметь расширение, например .sh(например, config.sh). Обычно это сценарий оболочки, который запускает некоторые другие утилиты, чтобы подтвердить, что у вас есть «нормальная» среда для компиляции. Другими словами, он проверит, чтобы убедиться, что у вас установлено все, что вам нужно.

Совет: Если это приложение на основе Python, а не файл конфигурации, вы должны найти файл с именем setup.py. Приложения Python, как правило, очень просты в установке. Чтобы установить это приложение от имени пользователя root (например, поместите sudo перед следующей командой под Ubuntu), выполните эту команду:

    $ python setup.py install

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

Запустите скрипт настройки в терминале. Как правило, вы можете (и должны!) Запускать свой конфигурационный скрипт с учетной записью обычного пользователя.

$ ./config

Скрипт отобразит некоторые сообщения, чтобы дать вам представление о том, что он делает. Зачастую сценарий дает вам представление о том, успешно он или нет, а в случае неудачи - некоторую информацию о причине сбоя. Если вы не получаете никаких сообщений об ошибках, то обычно можно предположить, что все прошло нормально.

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

Пример

В этом руководстве я собираюсь использовать текстовую программу чтения RSS под названием Newsbeuter в качестве примера типов ошибок, с которыми вы можете столкнуться при создании приложения. Для Newsbeuter, имя сценария настройки config.sh. В моей системе при запуске config.shвозникают следующие ошибки:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Проведя некоторые исследования, я обнаружил, что на самом деле sqlite3приложение было установлено. Однако, так как я пытаюсь собрать из исходного кода, это совет, который на config.shсамом деле ищет библиотеки разработки (заголовки) sqlite3. В Ubuntu большинство пакетов имеют связанный с ним пакет разработки, который заканчивается на -dev. (Другие платформы, такие как Fedora, часто используют суффикс пакета -develдля пакетов разработки.)

Чтобы найти подходящий пакет для пакета sqlite3разработки, мы можем использовать apt-cacheутилиту в Ubuntu (и, аналогично, yumутилиту в Fedora):

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Эта команда возвращает довольно большой список результатов, поэтому нам нужно проделать небольшую детективную работу, чтобы определить, какой пакет является подходящим. В этом случае соответствующий пакет оказывается libsqlite3-dev. Обратите внимание, что иногда пакет, который мы ищем, будет иметь libпрефикс, а не просто имя пакета плюс -dev. Это потому, что иногда мы просто ищем разделяемую библиотеку, которая может использоваться многими различными приложениями. Чтобы установить libsqlite3-dev, выполните типичную команду apt-get install в терминале:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Теперь нам нужно запустить config.shснова, чтобы убедиться, что мы решили эту проблему с зависимостями и у нас больше нет проблем с зависимостями. (Хотя я не буду показывать это здесь, в случае Newsbeuter мне также пришлось установить libcurl4-openssl-devпакет.) Кроме того, если вы устанавливаете пакет разработки (например libsqlite3-dev), а соответствующий пакет приложения (например, sqlite3) не уже установлено, большинство систем автоматически установят соответствующий пакет приложений одновременно.

Когда конфигурация будет выполнена успешно, в результате будет создан один или несколько файлов make. Эти файлы обычно называются Makefile(помните, что регистр имени файла имеет значение в Unix / Linux!). Если пакет сборки включает в себя подкаталоги, такие как srcи т. Д., Каждый из этих подкаталогов также будет содержать a Makefile.

Ошибки сборки и компиляции

Теперь мы готовы фактически скомпилировать приложение. Это часто называют строительством, а название заимствовано из реального процесса конструирования чего-либо. Различные «части» приложения, которые обычно представляют собой несколько файлов исходного кода, объединяются вместе, чтобы сформировать общее приложение. Утилита make управляет процессом сборки и вызывает другие приложения, такие как компилятор и компоновщик, для фактического выполнения работы. В большинстве случаев вы просто запускаете make (со своей учетной записью обычного пользователя) из каталога, в котором вы запустили конфигурацию. (В некоторых случаях, например, при компиляции приложений, написанных с использованием библиотеки Qt, вам потребуется вместо этого запускать другое приложение-оболочку, например qmake. Опять же, всегда проверяйте документы READMEи / или INSTALLдокументы для получения подробной информации.)

Как и в приведенном выше скрипте конфигурации, когда вы запускаете make (или аналогичную утилиту) в терминале, он отображает некоторые сообщения о том, что выполняется, и любые предупреждения и ошибки. Обычно вы можете игнорировать предупреждения, так как они в основном предназначены для разработчиков приложений и говорят им, что существуют некоторые стандартные методы, которые нарушаются. Обычно эти предупреждения не влияют на функцию приложения. С другой стороны, ошибки компилятора должны быть исправлены. С Newsbeuter, когда я запускал make, какое-то время все шло нормально, но потом я получил ошибку:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

Процесс make остановится, как только будет обнаружена первая ошибка. Обработка ошибок компилятора иногда может быть сложной задачей. Вы должны посмотреть на ошибки, чтобы найти подсказки о проблеме. Обычно проблема заключается в том, что некоторые заголовочные файлы, которые обычно имеют расширение .hили .hpp, отсутствуют. В случае ошибки выше, это (или должно быть!) Ясно, что проблема в том, что stfl.hзаголовочный файл не может быть найден. Как показывает этот пример, вы хотите просмотреть первые строки сообщения об ошибке и пройтись вниз, чтобы найти причину проблемы.

Посмотрев документацию Newsbeuter (которую я должен был сделать до того, как начал, но тогда эта часть руководства не будет иметь особого смысла!), Я обнаружил, что для этого требуется сторонняя библиотека под названием STFL. Так что же нам делать в этом случае? Что ж, мы, по сути, повторяем этот процесс для этой необходимой библиотеки: получите библиотеку и выполните для нее процесс configure-build-install, а затем возобновите сборку нужного приложения. Например, в случае STFL мне пришлось установить libncursesw5-devпакет для его правильной сборки. (Обычно нет необходимости повторять этап настройки нашего исходного приложения после установки другого необходимого приложения, но это также никогда не повредит.)

После успешной установки инструментария STFL процесс make для Newsbeuter прошел успешно. Процесс make обычно определяет, где он остановился (в точке ошибки). Таким образом, любые файлы, которые уже были успешно скомпилированы, перекомпилироваться не будут. Если вы хотите перекомпилировать все, вы можете запустить make clean all, чтобы удалить все скомпилированные объекты, а затем снова запустить make.

Установка

После успешного завершения процесса сборки вы готовы установить приложение. В большинстве случаев, чтобы установить приложение в общих областях файловой системы (например, /usr/binили /usr/share/bin, и т. Д.), Вам потребуется запустить установку от имени пользователя root. Установка действительно самый простой шаг во всем процессе. Для установки в терминале запустите:

$ make install

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

Когда вы создаете приложение из исходного кода, оно обычно не добавляет значок или ярлык в меню GUI в Ubuntu. Вам нужно будет добавить это вручную.

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

Тим Джонс
источник
Тим, я бы хотел прочитать твой урок, но ссылка, которую ты разместил, не работает.
gareth_bowles
6

Ну, ./configure --help даст вам много информации для GNU autotools, сгенерированных конфигурационных файлов. Большинство из них сводится к --with / - без включения функций (для них может потребоваться дополнительный параметр, например «shared», чтобы указать, где найти библиотеку).

Другими важными являются --prefix (по умолчанию / usr / local / большую часть времени), чтобы указать, куда устанавливать (если вы собираете пакеты, вы обычно хотите это как --prefix = / usr или, возможно, --prefix = / Opt / YourPackage).

В Linux / lib, / usr / lib и / usr / local / lib обычно ищутся в моем gcc и включаются в конфигурацию по умолчанию ldconfig. Если у вас нет веских причин, именно здесь вам нужны ваши библиотеки. Однако /etc/ld.so.conf может перечислять дополнительные записи.

сконфигурируйте и найдите их, просто попытавшись запустить "gcc -l" и посмотрев, нет ли ошибок. Вы можете добавить «-L» к вашему параметру CFLAGS, чтобы добавить дополнительные пути для поиска.

У вас может быть установлено несколько версий, и программное обеспечение, связанное с более старой версией, останется связанным с ним (запустите ldd, чтобы узнать привязку в Linux), но новые компиляции обычно нацелены на последнюю версию динамической библиотеки в вашей системе.

Большая часть программного обеспечения предполагает динамические библиотеки, особенно если она использует libtool, поэтому вы можете обнаружить, что нетривиальные приложения статически не собираются правильно.

ls -l - ваш лучший выбор для поиска установленных библиотек.

И вот где у меня нет информации; как хорошо играть с пакетами: не знаю. Когда это возможно, я стараюсь обернуть вещи в пакет, чтобы избежать проблемы.

Аарон Брейди
источник
4

«Как мне выяснить, какие аргументы передать ./configure?»

обычно: ./configure --help скажет вам, что вы хотите там.

«Как я могу узнать, какие библиотеки я установил и какие версии?»

Это зависит от системы. Один из способов - просто сделать так, find /|grep libname|lessкак обычно файлы библиотеки имеют версию в имени файла.

«Как я могу установить более одной версии библиотеки, не нарушая мою обычную систему?»

Опять же, зависит от системы и библиотеки. sudo make altinstallбудет создан версированное имя для вас. Файлы библиотеки, как правило, сами по себе версии. Имейте в виду, однако; поскольку версии часто создают символические ссылки на «нормализованное» имя, это может сломать вещи.

«Если я устанавливаю материал из источника в систему, которая в противном случае управляется с помощью пакетов, каков самый чистый способ сделать это?»

Использование параметров --prefix в ./configure и их размещение в любом месте /opt- хорошая практика.

Отказ от ответственности: я ни в коем случае не эксперт, но я использую Linux более 5 лет из линейки cmd (slackware, CentOS, redhat, ubuntu, misc others и OS X).

Филипп Б. Олдем
источник
4

Чтобы ответить на немного вашего вопроса, на днях я нашел хороший способ посмотреть, какие библиотеки вы установили и какие версии (это для Linux Debian, поэтому будет работать и с другими версиями).

dpkg --list

Вы должны получить действительно длинный список с таким выводом, как этот

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3
Марк Дэвидсон
источник
4

Саймон,

1.) ./configure --help предоставляет большое количество информации. Я предлагаю проверить это. Обычно он имеет опции для компиляции статических / динамически связанных библиотек, когда это необходимо.

2.) Библиотеки живут по пути динамического компоновщика. Обычно это устанавливается в /etc/ld.so.conf. Компоновщик ищет соответствующие библиотеки во многом как переменная среды PATH, соответствующая первой найденной.

3.) Как правило, это приводит к проблемам, так как вы должны перекомпилировать все, когда изменяется версия библиотеки. Если вы выполните поиск, вы, вероятно, найдете множество причин, по которым статическое связывание является плохой идеей. Я не делал это так долго, я не могу здесь подробно остановиться.

4.) Это немного сложно. Вы должны проверить путь к своей библиотеке, чтобы убедиться в этом. Библиотеки обычно имеют символическую ссылку на установленную версию.

например, libssh2.so.1 -> libssh2.so.1.0.0

Обычно люди управляют библиотеками и программами, которые они устанавливают, либо сворачивая свои собственные пакеты Debian, либо используя другую технику. Я управляю установленным программным обеспечением с помощью stow ( http://www.gnu.org/software/stow/ ), который очень прост и устанавливает библиотеку с помощью символических ссылок. Я нахожу это проще, поскольку мне не нужно собирать / устанавливать / тестировать пакет deb / rpm.

5.) Несколько версий библиотек могут быть обычно установлены в каталогах библиотек. Библиотеки, связанные с исполняемыми файлами, будут оставаться связанными с версиями, с которыми они были связаны. запуск ldd на исполняемом файле скажет вам, с какими библиотеками связан исполняемый файл.

6.) Как я уже упоминал ранее, использование собственных пакетов Debian или использование stow, вероятно, является самым чистым решением.

7.) Я не могу говорить о Mac OSX, но для Linux лучше всего использовать систему упаковки дистрибутива.

8.) Вероятно, многие проблемы будут решены с помощью ldd и выяснения, с какой версией что-то связано или какая библиотека, связанная с исполняемым файлом, не может быть найдена. pkg-config поможет вам, но только для программного обеспечения, которое его использует. Он не является частью стандартной системы сборки автоинструментов, хотя в наши дни он популярен.

Ян Льюис
источник
4

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

Мне не нравится идея «make install», которая потенциально мешает моей системе, но, как говорили другие, обычно гораздо меньше проблем с установкой в ​​/ usr / local вместо использования --prefix для установки в другом месте. Итак, я подарил / usr / local своему обычному (непривилегированному) пользователю. Таким образом, «make install» гарантированно не будет связываться с важными системными файлами. (Это, очевидно, не будет работать на многопользовательских системах. Однако это здорово для виртуальных серверов.)

ithinkihaveacat
источник
4

Хотя это не было явно в вашем списке вопросов, вы упоминаете в своем предисловии:

./configure && make && sudo make install обычно достаточно, но иногда это не работает - и когда это не так, я часто зацикливаюсь.

Когда я застреваю в Debian или Ubuntu, я использую auto-apt, который автоматически устанавливает пакеты, содержащие файлы, которые не могут быть найдены в сконфигурированных файлах.

Видеть:

Еще одним инструментом, который вам может пригодиться, является CheckInstall, он добавляет установленные приложения make installв список установленных пакетов: https://help.ubuntu.com/community/CheckInstall.

Swoogan
источник
3

Для OS X:

  • Как мне выяснить, какие аргументы передать ./configure?

./configure --help

  • Каковы фактические различия между разделяемой и статически связанной библиотекой? Почему я не могу просто статически связать все (оперативная память и дисковое пространство дешевы в наши дни) и, следовательно, избежать странных конфликтов версий библиотеки?

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

  • Как разделяемые библиотеки работают в OS X / Linux - где они живут в файловой системе, как ./configure && make находит их, что на самом деле происходит, когда они связаны с

Системные библиотеки находятся в / usr / lib.

Библиотеки, которые вы сами компилируете, живут в / usr / local / lib (/ usr / local является флагом --prefix по умолчанию для ./configure).

Переменные окружения DYLD_FALLBACK_LIBRARY_PATH и LD_LIBRARY_PATH позволяют указать, какие папки нужно искать, поэтому / usr / local / lib должна быть там в начале списка.

  • Как я могу установить более одной версии библиотеки, не нарушая мою обычную систему?

Установите все в / usr / local - с указанными выше переменными среды версия в / usr / local / lib имеет приоритет над версией в / usr / lib в вашей среде.

  • Если я устанавливаю материал из исходного кода в систему, которая в противном случае управляется с помощью пакетов, каков самый чистый способ сделать это?

Установите в / usr / local. В Ubuntu я сначала пытаюсь использовать checkinstall, чтобы создать пакет deb.

  • Предполагая, что мне удается скомпилировать что-то из исходного кода, как я могу затем упаковать это, чтобы другим людям не приходилось прыгать через те же обручи? Особенно на OS X ....

Я бы сказал, задокументируйте шаги компиляции в блоге.

Альф Итон
источник