自动工具可以创建多平台makefiles

问题描述:

我有一个插件项目,我已经开发了几年,插件可以与[主应用程序版本,第三方库版本,32位与64位]。是否有一种(干净的)方式来使用autotools来创建一个生成插件的所有版本的生成文件。自动工具可以创建多平台makefiles

据我所知,通过浏览autotools文档可以看出,最接近我想要的是有N个独立的项目副本,每个副本都有自己的makefile。 (a)我需要不断在所有不同的副本中传播代码更​​改,并且(b)复制项目时存在大量浪费的空间。有没有更好的办法?

编辑:

我一直在我自己的滚动解决方案一段时间,我都看上生成文件和一些Perl脚本追捕各种第三方库版本等。因此,我对其他非自动工具解决方案开放。对于其他构建工具,我希望它们对于最终用户来说非常容易安装。这些工具还需要足够聪明才能捕捉各种第三方库和头文件,而不会遇到大量麻烦。我主要是在寻找一个linux解决方案,但是一个也适用于Windows和/或Mac的应用程序将是一个奖金。

据我所知,你不能那样做。但是,你是否坚持autotools?既不是CMake也不是SCons一个选项?

+0

由于运行此。我正在读两篇文章,看看哪些更有可能处理构建过程的一些复杂性,例如调用特定应用程序特定的构建包装器,而不是直接调用gcc。 – 2008-11-27 20:17:25

我们试过了,它不起作用!所以我们现在使用SCons

一些文章到这个话题:12

编辑: 一些小例子,为什么我爱SCons的:

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

有了这行代码添加GLib库的编译环境( env)。不要忘记User Guide,这对学习SCons非常有用(你真的不需要知道Python!)。对于最终用户,您可以尝试使用PyInstaller或其他类似的东西。

make相比,你使用Python,所以一个完整的编程语言!考虑到这一点,你可以做一切(或多或少)。

+0

我会看看scons。我以前没听说过。 – 2008-11-27 20:16:03

如果你的问题是:

我可以使用一些计算机A上的自动工具来创建一个单一的普遍生成文件,将所有其他计算机上工作?

然后答案是“否”。 autotools甚至没有试图这样做的幌子。它们被设计为包含便携式代码,用于确定如何在目标机器上创建可行的生成文件。

如果你的问题是:

我可以使用自动工具来配置需要在不同的机器上运行,使用不同版本的该我的插件的工作原理与主要的软件,加上各种第三方库软件,更不用说32位和64位问题了?

那么答案是“是”。 autotools被设计为能够做到这一点。此外,他们在Unix,Linux,MacOS X,BSD上工作。

我有一个程序SQLCMD(它预编译了同名十年以上的微软程序),它可以与IBM Informix数据库一起工作。它检测客户端软件(称为IBM Informix ESQL/C,IBM Informix ClientSDK或CSDK的一部分)的版本是否安装,以及它是32位还是64位。它还检测软件的安装版本,并根据支持产品中的功能调整其功能。它支持在17年左右发布的版本。它是自动配置的 - 我必须为Informix功能编写一些autoconf宏,以及其他一些gizmos(高分辨率时序,/ dev/stdin等)。但它是可行的。另一方面,我不尝试并发布一个适合所有客户机器和环境的makefile;有太多的可能性,这是明智的。但autotools为我(和我的用户)照顾细节。他们所做的只是:

./configure 

这比编制makefile文件更容易。 (呵呵,前10年,这个程序是手工配置的,尽管我设置了很好的默认设置,但人们很难做到这一点,这就是为什么我转向自动配置:它使得它更容易人安装)


福兹先生评论道:

我想要的东西之间。在我的情况下,客户将在同一台机器上使用同一基本应用程序的多个版本和位数。我不担心交叉编译,例如在Linux上构建Windows二进制文件。

你需要单独构建32位和64位版本的插件吗? (我假设是 - 但是你可以让我感到惊讶。)所以,你需要提供一个机制,为用户说

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

(其中tppkg是您的第三方封装代码,且位置)但是,请记住可用性:用户提供的提供的选项越少越好;相反,不要硬编码应该是可选的东西,比如安装位置。通过一切手段寻找默认位置 - 这很好。并默认你找到的东西的狡猾。也许如果你找到了32位和64位版本,那么你应该建立两者 - 但这需要仔细构建。您始终可以回显“检查TP包装...”并指出您找到的内容以及您在哪里找到它。然后安装程序可以更改选项。确保你在'./configure --help'中记录什么是选项;这是标准的autotools练习。

不要做任何互动的事情;应该运行配置脚本,报告它的功能。Perl Configure脚本(注意大写字母 - 它是一个完全独立的自动配置系统)是为数不多的密集交互式配置系统之一(这可能主要是因为它的传统;如果重新开始,它很可能是非-互动)。这样的系统比非交互系统更麻烦。

交叉编译很困难。我从来不需要这么做,谢天谢地。


福兹先生还表示:

感谢额外的意见。我在寻找类似:

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

它会在一个生成文件同时创建32位和64位的目标为当前平台。

嗯,我相信它可以做到;我不太确定,通过两次单独的配置运行与完全重建之间的比较,它是值得的。您可能想要使用:

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

这表示两个单独的目录。您必须决定如何构建,但假设您有两个子目录,例如'obj-32'和'obj-64',用于存储单独的目标文件集。您也想安排你的makefile线沿线的:

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

TPPKG32DIR = @[email protected] 
TPPKG64DIR = @[email protected] 

OBJ32DIR = obj-32 
OBJ64DIR = obj-64 

BUILD_32 = @[email protected] 
BUILD_64 = @[email protected] 

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 

这假定该插件将是一个共享对象。这里的想法是autotool会检测第三方包的32位或64位安装,然后进行替换。如果需要32位软件包,BUILD_32宏将被设置为build_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套件中的标准设施来完成。

除非你自己创建一个仔细(甚至是无情)的对称makefile,否则它将无法可靠地工作。

+0

我想要介于两者之间的东西。在我的情况下,客户将在同一台机器上使用同一基本应用程序的多个版本和位数。我不担心交叉编译,例如在Linux上构建Windows二进制文件。 – 2008-11-27 18:09:15

你有没有考虑过在多个构建目录中使用单个项目? 如果你的automake的项目是在一个适当的方式来实现(即:不喜欢GCC)

以下是可能的:

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

你能够通过不同的配置参数,如包含目录和编译器(交叉编译器IE)。

然后你可以甚至在一个单一的发出呼叫运行

make -C build1 -C build2 -C build3