Может ли autotools создавать мультиплатформенные make-файлы - PullRequest
2 голосов
/ 27 ноября 2008

У меня есть проект плагина, который я разрабатывал в течение нескольких лет, и этот плагин работает с многочисленными комбинациями [версия основного приложения, сторонняя версия библиотеки, 32-битная и 64-битная]. Есть ли (чистый) способ использования автоинструментов для создания одного make-файла, который собирает все версии плагина.

Насколько я могу судить по скиммингу в документации по автоинструментам, самое близкое приближение к тому, что я хотел бы, - это иметь N независимых копий проекта, каждый со своим собственным make-файлом. Это кажется немного неоптимальным для тестирования и разработки, так как (а) мне нужно было бы постоянно распространять изменения кода по всем различным копиям и (б) много места было потрачено впустую при дублировании проекта столько раз. Есть ли лучший способ?

РЕДАКТИРОВАТЬ:

Я какое-то время катал свое собственное решение, где у меня есть причудливый make-файл и несколько сценариев perl для поиска различных версий библиотек сторонних производителей и т. Д. Поэтому я открыт для других решений, не относящихся к автоинструментам. Что касается других инструментов сборки, я бы хотел, чтобы их было очень легко установить конечным пользователям. Инструменты также должны быть достаточно умными, чтобы выслеживать различные сторонние библиотеки и заголовки без огромного количества проблем. Я в основном ищу решение для Linux, но оно также подойдет для Windows и / или Mac.

Ответы [ 4 ]

6 голосов
/ 27 ноября 2008

Если ваш вопрос:

Могу ли я использовать автоинструменты на некотором компьютере A для создания единого универсального файла сборки, который будет работать на всех других машинах?

тогда ответ "Нет". Автоинструменты даже не делают вид, что пытаются это сделать. Они разработаны для того, чтобы содержать переносимый код, который определит, как создать работающий make-файл на целевом компьютере.

Если ваш вопрос:

Могу ли я использовать автоинструменты для настройки программного обеспечения, которое должно работать на разных компьютерах, с разными версиями основного программного обеспечения, с которым работает мой плагин, а также с различными сторонними библиотеками, не говоря уже о проблемах с 32-разрядными и 64-разрядными?

тогда ответ "Да". Автоинструменты предназначены для этого. Кроме того, они работают на Unix, Linux, MacOS X, BSD.

У меня есть программа SQLCMD (которая предшествует одноименной программе Microsoft на десять и более лет), которая работает с базами данных IBM Informix. Он обнаруживает, что версия клиентского программного обеспечения (называемая IBM Informix ESQL / C, часть IBM Informix ClientSDK или CSDK) установлена, и является ли она 32-битной или 64-битной. Он также определяет, какая версия программного обеспечения установлена, и адаптирует его функциональные возможности к тому, что доступно в поддерживаемом продукте. Он поддерживает версии, которые были выпущены в течение 17 лет. Он настроен автоматически - мне пришлось написать несколько макросов autoconf для функциональности Informix и для нескольких других штуковин (высокое разрешение, наличие / dev / stdin и т. Д.). Но это выполнимо.

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

./configure

Это проще, чем работать над тем, как редактировать make-файл. (О, в течение первых 10 лет программа настраивалась вручную. Людям было трудно это сделать, хотя у меня были довольно хорошие настройки по умолчанию. Именно поэтому я перешел на автоматическую настройку: это значительно облегчает люди для установки.)


Мистер Фуз прокомментировал:

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

Вам нужна отдельная сборка вашего плагина для 32-битной и 64-битной версий? (Я бы предположил, что да, но вы могли бы меня удивить.) Поэтому вам нужно предоставить механизм, чтобы пользователь мог сказать

./configure --use-tppkg=/opt/tp/pkg32-1.0.3

(где tppkg - это код вашего стороннего пакета, а местоположение определяется пользователем.) Однако следует учитывать удобство использования: чем меньше таких опций пользователь может предоставить , тем лучше; против этого не стоит жестко кодировать вещи, которые должны быть необязательными, такие как места установки. Во что бы то ни стало посмотрите в локациях по умолчанию - это хорошо. И по умолчанию к кусочкам материала, который вы найдете. Может быть, если вы найдете как 32-битную, так и 64-битную версии, вам следует собрать обе - хотя это потребует тщательной разработки. Вы всегда можете повторить «Проверка TP-пакета ...» и указать, что вы нашли и где вы его нашли. Затем установщик может изменить параметры. Убедитесь, что вы указали в './configure --help' опции; это стандартная практика автоинструментов.

Не делайте ничего интерактивного, хотя; скрипт configure должен запуститься, сообщив, что он делает. Скрипт Perl Configure (обратите внимание на заглавную букву - это полностью отдельная система автоматической настройки) - это одна из немногих оставшихся интенсивно интерактивных систем конфигурации (и это, вероятно, в основном из-за ее наследства; если запускать заново, он, скорее всего, будет быть не интерактивным). Такие системы более сложны в настройке, чем неинтерактивные.

Кросс-компиляция сложна. Мне никогда не нужно было это делать, слава богу.


Мистер Фуз также прокомментировал:

Спасибо за дополнительные комментарии. Я ищу что-то вроде:

./configure --use-tppkg=/opt/tp/pkg32-1.0.3 --use-tppkg=/opt/tp/pkg64-1.1.2

где он будет создавать 32-битные и 64-битные цели в одном make-файле для текущей платформы.

Ну, я уверен, что это можно сделать; Я не уверен, что это стоит делать по сравнению с двумя отдельными конфигурациями с полной перестройкой между ними. Возможно, вы захотите использовать:

./configure --use-tppkg32=/opt/tp/pkg32-1.0.3 --use-tppkg64=/opt/tp/pkg64-1.1.2

Это указывает на две отдельные директории. Вам нужно решить, как вы собираетесь выполнять сборку, но, вероятно, у вас будет две подкаталоги, такие как 'obj-32' и 'obj-64' для хранения отдельных наборов объектных файлов. Вы также разместите свой make-файл в соответствии с:

FLAGS_32 = ...32-bit compiler options...
FLAGS_64 = ...64-bit compiler options...

TPPKG32DIR = @TPPKG32DIR@
TPPKG64DIR = @TPPKG64DIR@

OBJ32DIR = obj-32
OBJ64DIR = obj-64

BUILD_32 = @BUILD_32@
BUILD_64 = @BUILD_64@

TPPKGDIR =
OBJDIR   =
FLAGS    =

all:    ${BUILD_32} ${BUILD_64}

build_32:
    ${MAKE} TPPKGDIR=${TPPKG32DIR} OBJDIR=${OBJ32DIR} FLAGS=${FLAGS_32} build

build_64:
    ${MAKE} TPPKGDIR=${TPPKG64DIR} OBJDIR=${OBJ64DIR} FLAGS=${FLAGS_64} build

build:  ${OBJDIR}/plugin.so

Предполагается, что плагин будет общим объектом. Идея заключается в том, что автоинструмент будет обнаруживать 32-битные или 64-битные установки для стороннего пакета, а затем делать замены. Макрос BUILD_32 будет установлен в build_32, если требуется 32-битный пакет, и в противном случае останется пустым; макрос BUILD_64 будет обрабатываться аналогично.

Когда пользователь запускает 'make all', он сначала создает цель build_32, а затем цель build_64. Чтобы создать цель build_32, он будет перезапущен make и настроит флаги для 32-битной сборки. Аналогично, для построения цели build_64 он будет перезапускать make и настраивать флаги для 64-битной сборки. Важно, чтобы все флаги, на которые влияют 32-битные или 64-битные сборки, были установлены при рекурсивном вызове make, и чтобы правила для создания объектов и библиотек были написаны тщательно - например, правило для компиляции исходного кода в Объект должен быть осторожен, чтобы поместить объектный файл в правильный каталог объектов - например, используя GCC, вы должны указать (в правиле .c.o):

${CC} ${CFLAGS} -o ${OBJDIR}/$*.o -c $*.c

Макрос CFLAGS будет содержать значение $ {FLAGS}, которое имеет дело с битами (например, FLAGS_32 = -m32 и FLAGS_64 = -m64 , and so when building the 32-bit version, FLAGS = -m32 would be included in the Макрос CFLAGS`.

Остаточные проблемы в автоинструментах связаны с определением 32-битных и 64-битных флагов. Если худшее приходит к худшему, вам придется написать для этого макросы самостоятельно. Тем не менее, я ожидаю (не исследовав это), что вы можете сделать это, используя стандартные средства из пакета autotools.

Если вы не создадите себе тщательно (даже безжалостно) симметричный make-файл, он не будет работать надежно.

4 голосов
/ 27 ноября 2008

Насколько я знаю, ты не можешь этого сделать. Тем не менее, вы застряли с автоинструментами? CMake и SCons не являются опцией?

1 голос
/ 27 ноября 2008

Мы попробовали это, и это не работает! Поэтому мы используем сейчас SCons .

Некоторые статьи на эту тему: 1 и 2

Edit: Небольшой пример того, почему я люблю SCons:

env.ParseConfig('pkg-config --cflags --libs glib-2.0')

С помощью этой строки кода вы добавляете GLib в среду компиляции ( env ). И не забывайте Руководство пользователя , которое просто отлично подходит для изучения SCons (вам действительно не обязательно знать Python!). Для конечного пользователя вы можете попробовать SCons с PyInstaller или чем-то подобным.

И по сравнению с make вы используете Python, поэтому полный язык программирования! Имея это в виду, вы можете делать все что угодно (более или менее).

0 голосов
/ 10 июня 2010

Вы когда-нибудь задумывались об использовании одного проекта с несколькими каталогами сборки? если ваш проект automake реализован должным образом (т.е. НЕ как gcc)

возможно следующее:

mkdir build1 build2 build3
cd build1
../configure $(YOUR_OPTIONS)
cd build2
../configure $(YOUR_OPTIONS2)
[...]

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

Вы можете даже запустить это в один вызов, набрав

make -C build1 -C build2 -C build3
...