在`lib_LTLIBRARIES`中使用configure替换

问题描述 投票:0回答:2

我正在尝试使用Autotools为我的共享库实现“多版本选项”:如果用户启用它,库必须能够与其他版本的自身共存。这意味着二进制文件的名称必须包含版本字符串,或者至少包含区别于其他版本的任何字符串。

libtool有一个选项,-release,就是这样做的。但是,正如here所解释的那样,这不适用于我的目的,因为至少有一个文件不会附加任何后缀,这将与包的其他版本产生冲突:

4.3. Multiple libraries versions

虽然libtool旨在处理在系统上实现相同API(甚至是ABI)的多个库的存在,但是分发使得这种必要性没有实际意义。另一方面,安装多个版本的库并不常见,实现了多个API,允许消费者选择他们支持的版本。例如,Gtk +和Glib就属于这种情况。

第一反应是结合两个选项,-release-version-info;但这会是错误的。当使用-release时,静态存档,.a扩展名,libtool存档(参见Section 6, “Libtool Archives”)和链接编辑器使用的.so文件不会附加修订版,这意味着无法安装两个不同版本的库同时。

在这种情况下,最好的选择是将库的版本信息的一部分附加到库的名称,例如Glib的libglib-2.0.so.0 soname。为此,Makefile.am中的声明必须如下:

lib_LTLIBRARIES = libtest-1.0.la

libtest_1_0_la_LDFLAGS = -version-info 0:0:0

我刚才引用的段落也包含了这个问题的一般解决方案,即手动将后缀添加到二进制文件的名称中。但是,如果库经常更改版本,这可能是一项很累人的任务,并且肯定不适合我的情况,只有当用户启用选项时才必须附加后缀。

我已经能够在configure.ac中准备环境,以便在禁用“multiversion选项”时将以下两个变量替换设置为空字符串,并且在启用它们时将它们设置为:

AC_SUBST([LIBRARY_SUFFIX_1], [-1.2])
AC_SUBST([LIBRARY_SUFFIX_2], [_1_2])

但是当我尝试将这些替换导出到src/Makefile.am时,如下例所示,

lib_LTLIBRARIES = libfoo@[email protected]

libfoo@LIBRARY_SUFFIX_2@_la_SOURCES = \
    foo.c

libfoo@LIBRARY_SUFFIX_2@_la_LDFLAGS = \
    -version-info "2:0:0"

libfoo@LIBRARY_SUFFIX_2@_la_LIBADD = 

我从configure收到以下错误消息:

src/Makefile.am:17: warning: variable 'libfoo@LIBRARY_SUFFIX_2@_la_SOURCES' is defined but no program or library has 'libfoo@LIBRARY_SUFFIX_2@_la' as canonical name (possible typo)
src/Makefile.am:23: warning: variable 'libfoo@LIBRARY_SUFFIX_2@_la_LIBADD' is defined but no program or library has 'libfoo@LIBRARY_SUFFIX_2@_la' as canonical name (possible typo)
src/Makefile.am:20: warning: variable 'libfoo@LIBRARY_SUFFIX_2@_la_LDFLAGS' is defined but no program or library has 'libfoo@LIBRARY_SUFFIX_2@_la' as canonical name (possible typo)

经过一些研究后,我发现了几个完全符合我试图做的包(#1#2#3#4#5#6#7#8#9#10#11)。我在stackoverflow上也发现了this similar question,但答案并没有多大帮助。我甚至发现了一个article in the official guide of Automake,提出了一个与我想要做的非常类似的例子,但如果我尝试逐字复制并粘贴它,我仍会得到相同的错误消息。

另一方面,this other article from the same guide说明了这一点

您不能将配置替换(例如,'@FOO@'或'$(FOO)',其中FOO通过AC_SUBST定义)到_SOURCES变量中。这样做的原因有点难以解释,但足以说它根本不起作用。如果您尝试执行此操作,Automake将给出错误。

但是我没有将配置替换放入_SOURCES变量中,我想要做的是从配置替换中获取_SOURCES变量的名称本身。而且我发现至少有11个包就是这样做的。

所以问题是:我做错了什么?是否有人能够生成一个最小的工作示例,其中lib_LTLIBRARIES的内容取自配置替换?

autotools configure automake libtool multiple-versions
2个回答
1
投票

我不明白为什么-release不会为你工作,所以我会把这个解决方案留给这个答案。程序类似,但将创建不同的.so文件名(例如libfoo-1.2.solibfoo.so),但相同的.a名称。

configure.AC

AC_INIT([myproject],[0.1],[[email protected]])
AC_PREREQ([2.69])
AC_CONFIG_SRCDIR([src/foo.c])
AC_PROG_CC
AC_ARG_ENABLE([multi], AS_HELP_STRING([--enable-multi], [Enable multi]))
AM_INIT_AUTOMAKE([1.15 foreign])
AM_PROG_LIBTOOL
AM_CONDITIONAL([MULTI_NAME], [test "x$enable_multi" = "xyes"])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Makefile.阿门

SRCS=src/foo.c
lib_LTLIBRARIES=
if MULTI_NAME
lib_LTLIBRARIES+=libfoo-1.2.la
libfoo_1_2_la_SOURCES=$(SRCS)
else
lib_LTLIBRARIES+=libfoo.la
libfoo_la_SOURCES=$(SRCS)
endif

./configure ; make创建libfoo.so.0.0.0(在Linux上默认启用版本控制)。 ./configure --enable-multi ; make创造了libfoo-1.2.so.0.0.0

这不会给我你看到的警告。当我尝试使用AC_SUBST时,我看到了相同的警告;它构建库好。


0
投票

我找到了问题的答案。如果我对lib_LTLIBRARIES的内容和libXXX_la_SOURCES libXXX_la_LDFLAGS libXXX_la_LIBADD的名称使用相同的配置替换,一切似乎都可以正常工作,如下面的场景:

configure.ac的内容:

...

AC_SUBST([CUSTOM_NAME], [foo])

...

src/Makefile.am的内容:

...

lib_LTLIBRARIES = lib@[email protected]

lib@CUSTOM_NAME@_la_SOURCES = \
    foo.c

lib@CUSTOM_NAME@_la_LDFLAGS = \
    -version-info "2:0:0"

lib@CUSTOM_NAME@_la_LIBADD = 

...

但是,出于某种原因,只要我使用两个不同的配置替换,即使它们包含相同的文本,我也会得到上面的错误。因此,不接受以下方案:

configure.ac的内容:

...

AC_SUBST([CUSTOM_NAME], [foo])
AC_SUBST([ANOTHER_NAME], [foo])

...

src/Makefile.am的内容:

...

lib_LTLIBRARIES = lib@[email protected]

lib@ANOTHER_NAME@_la_SOURCES = \
    foo.c

lib@ANOTHER_NAME@_la_LDFLAGS = \
    -version-info "2:0:0"

lib@ANOTHER_NAME@_la_LIBADD =

...
© www.soinside.com 2019 - 2024. All rights reserved.