Makefiles, «configure» файлы и другие инструменты компиляции - как они работают?Почему они работают так, как работают? - PullRequest
9 голосов
/ 22 марта 2011

Я все еще новичок в мире UNIX / Linux и, в частности, в связанных инструментах, таких как компилятор GCC.А именно, я все еще новичок в make-файлах и подобных вещах (я использую MinGW в Windows), так как до сих пор большая часть моей разработки была с IDE, такими как Visual Studio и Eclipse.

Когда я открываю типичныйпапка проекта, я вижу файлы, подобные этим:

configure
make
INSTALL
install-sh  (or a variant)

Здесь есть несколько вещей, которые я не понимаю, и мои основные вопросы таковы:

  1. Чторазница между ними, и зачем нам каждый?(В мире IDE все, что у вас есть, это файл проекта; вот и все. Поэтому я запутался, почему у нас здесь больше, чем просто make-файл.)

  2. Как создаются эти файлы?Для небольших проектов вы, вероятно, могли бы написать их вручную, но для больших проектов, таких как GCC, было бы даже смешно пытаться.Мне показалось, что редактировать эти файлы было больно, и я пришел к выводу, что я не должен изменять их вручную.Но если так, то какие инструменты обычно используют люди для добавления и изменения этих файлов?

  3. Почему они не используют подстановочные знаки внутри make-файла?Почему для каждого отдельного объектного файла существует одна строка?Это из-за ограничения или есть какое-то преимущество?

  4. В чем разница между наличием сценария оболочки, который вызывает компилятор для каждого файла, и наличием make-файла? что делает то же самое?В Windows мне очень хотелось бы просто создать командный файл внутри папки и скомпилировать все с этим - не нужно больше, чем один файл.Какая разница?Почему не существует только одного .sh файла для компиляции всего?

Бонусный вопрос:

  • Существует ли "стандартный" формат make-файла?Я видел различные make инструменты, которые не принимают форматы друг друга ... как я знаю, что использовать?Является ли GCC обычным инструментом здесь, или есть какой-то стандарт, которому все должны следовать?

У меня, вероятно, возникнет больше вопросов, когда я узнаю больше о структуре подобных проектов, но пока этимои самые большие вопросы:)

Ответы [ 3 ]

15 голосов
/ 22 марта 2011
  1. В вашем среднем пакете каждый из этих файлов имеет свое назначение.Это согласуется с философией Unix «каждая программа должна делать что-то одно и делать это хорошо».В большинстве проектов вы увидите такие файлы, как:

    • configure
    • configure.ac
    • Makefile
    • Makefile.in
    • Makefile.am
    • install-sh
    • INSTALL

    configure (обычно) сценарий оболочки, который проверяет вашу системудля всех необходимых функций, прежде чем строить что-либоMakefile.in - это шаблон для Makefile.Результаты тестов конфигурации подставляются в Makefile.in для генерации Makefile.Это относится к людям, имеющим вещи (компиляторы, заголовки, библиотеки) по непонятным путям, кросс-компиляцию (например, сборку для ARM на x86), дополнительную поддержку библиотек (некоторые программы имеют дополнительные функции, которые можно включать или выключать),компиляция с разными опциями и тд.Написание единого универсального Makefile на самом деле очень сложно .

    Как вы заметили, сам скрипт configure - беспорядок.Это не предназначено для того, чтобы быть увиденным смертными глазами, или отредактировано смертными руками.На самом деле это результат компиляции configure.ac с использованием программы под названием autoconf.autoconf - это пакет макросов для макропроцессора m4 и обертка для него, который в то время был единственным хорошим инструментом для такого рода вещей (autoconf действительно довольно старое программное обеспечение, но оно устарело на удивление хорошо).autoconf позволяет разработчику легко писать тесты для проверки заголовков, библиотек или программ, необходимых для сборки программного обеспечения (и это меняется от программы к программе).

    Если вы покопаетесь немного глубже, выобратите внимание, что Makefile.in также имеет тенденцию быть немного уродливым.Это связано с тем, что написание хороших Makefile s часто представляет собой типичный пример, и это вдохновило другой инструмент, automake.automake компилирует Makefile.am (который часто короткий и декларативный) в Makefile.in (который огромен), который затем компилируется в Makefile с помощью configure (по существу).

    install-shскрипт, который распространяется с automake, но скопирован в другие пакетыОн существует в качестве замены, если версия install в системе - дерьмо (install копирует файлы в установочный каталог. Некоторые действительно старые системы имели испорченные версии install, и automake довольно консервативно отбрасывает предупреждениядля старых систем).Некоторые другие сценарии, выполняющие аналогичные роли: compile, depcomp и ylwrap.

    INSTALL - это просто документ, описывающий, как установить пакет.Обычно это стандартное содержимое, скопированное в пакет с помощью automake.

  2. Я уже ответил на это, но вот краткое изложение:

    • configure.ac ==[autoconf]=> configure
    • Makefile.am ==[automake]=> Makefile.in ==[configure]=> Makefile

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

  3. Подстановочные знаки иногда используются в Makefile s.Например, GNU Make поддерживает функцию $(wildcard), где вы можете написать что-то вроде:

    SOURCES := $(wildcard src/*.c)

    Основная причина, по которой такие функции, как $(wildcard), не используются, заключается в том, что ониявляются расширениями, и automake очень старается сгенерировать Makefile s, которые будут работать с любым POSIX-совместимым make.После того, как проект становится зрелым, список файлов для компиляции все равно не сильно меняется.

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

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

Если у вас есть правило Makefile, например:

foo.out: foo.in
        generate-foo foo.in

Он сообщает make, что если foo.in является новее , чем foo.out, то можно создать новый foo.out, выполнив generate-foo foo.in.Это экономит много лишней работы над большими проектами, где вы можете изменить только один или два файла между перекомпиляциями.

Ваш бонусный вопрос кажется немного некорректным.Наиболее распространенным make, вероятно, является GNU Make, хотя я бы предположил, что BSD make будет секунда, за которой последуют различные проприетарные версии make, поставляемые с Solaris, AIX и т. Д.

Все они принимают одну и ту же базовую структуру в Makefile (потому что POSIX так говорит), но могут иметь специфичные для поставщика расширения синтаксиса.

GCC не является инструментом сборки, подобным make.GCC - это компилятор командной строки, похожий на cl.exe в Windows.

5 голосов
/ 22 марта 2011

Есть много причин для разных вещей, но в итоге все сводится к переносимости.Во время Unix-войн все платформы были разными, и люди пытались создать программное обеспечение, которое могло бы работать на максимально возможном количестве.Так что общие знаменатели должны были быть найдены.sh был одной из таких общих черт, поэтому скрипты configure были написаны так, чтобы использовать максимально переносимый sh.Максимальная переносимость подразумевает использование минимального набора функций.Различные реализации make сильно различаются по функциям, которые они поддерживают, поэтому были написаны файлы Makefile, которые использовали как можно меньше функций.Сегодня дела обстоят немного лучше, но проблемы с переносимостью по-прежнему способствуют тому, что вы видите.

2 голосов
/ 22 марта 2011
  1. configure - это скрипт, который устанавливает среду сборки и, возможно, генерирует make-файл. С make вы строите проект, с make install или install.sh или подобным, вы устанавливаете скомпилированные файлы. Если вы хотите проверить что-то локально, вы можете пропустить последнюю часть, и она будет отдельной.
  2. Вы можете использовать GNU autotools .
  3. Можете ли вы привести конкретные примеры? Make-файлы поддерживают шаблоны, и они время от времени используются.
  4. Makefile обрабатывает зависимости и автоматическую перекомпиляцию только необходимых файлов, если вы что-то изменили в исходном файле, а затем решили пересобрать проект. С командным файлом вы будете перекомпилировать все, с Makefiles вы только компилируете то, что было изменено.
...