寻求解释:libtool,automake,共享库(和Fortran)

我遇到的问题已经解决了。我发布这个是为了解释为什么解决方案实际工作的解释。我之前得到了很好的反馈。 我有一个使用非常简单的构建系统的遗留代码库,我的项目是将其迁移到Autotools进行自定义,特别是构建共享库。主库是用C语言编写的,但也必须可以从Fortran链接(用于遗留目的),并在F77中与一些测试代码一起分发。作者将源代码组织成模块......
src_module1/
src_module2/
...
testc/
testf77/
他们通过编译src _ * /目录中的代码并使用ranlib归档对象来构建库
lib/libmain.a
。 我的第一种方法是分别从每个src _ * /构建一个共享库,并将所有这些共享库“链接”到一个共享库中。使用Autotools,
src_module1/Makefile.am
将包含
noinst_LTLIBRARIES = libmodule1.la
libmodule1_la_SOURCES = ...
对于其他模块等等,最后
lib/Makefile.am
只需要:
lib_LTLIBRARIES = libmain.la
libmain_la_SOURCES =
libmain_la_LIBADD = $(top_srcdir)/src_module1/libmodule1.la ...
这看起来很完美。但是,当testc /中的代码被编译并链接到libmain.la时,会发出“找不到符号”错误。 认为这是libtool或共享库的一个问题,我尝试仅构建静态,基本上将所有ѭ6改为
.a
,将所有ѭ8改为
_LIBRARIES
。同样的问题。但是,这一次,当尝试链接libmain.a本身时,注意到错误“ranlib:warning for library:libmain.a目录是空的(库中没有对象文件成员定义全局符号)”。 我发现的解决方案似乎是一个黑客。我没有为任何src _ * /目录构建Makefile,而是仅用于lib /目录,其Makefile.am有以下行:
lib_LTLIBRARIES = libmain.la
libmain_la_SOURCES = [all sources from all ../src_modules/ ]
这很有效。 testc中编译的程序/链接libmain.la没有问题。其中一个“模块”是一组Fortran绑定,它们包含库中的其他C函数。甚至testf77中的Fortran代码也正确地链接到了libmain.la。 有人可以仔细解释当libtool构建共享库时会发生什么吗?甚至在构建静态库时?为什么几个静态库无法链接在一起构成一个静态库?为什么符号仅在libtool / ranlib“从源”构建库时可用?那么安装一个共享/静态库,比如将它移到/ usr / local / lib那里会发生什么呢?关于静态和共享库的维基百科文章对我来说不够详细。 我非常感谢所有努力来理解我的长篇大论的问题。     
已邀请:
你最初尝试过的应该是什么。我一直在使用这种设置(在C ++上下文中)。它也有文档记录,也是Automake测试套件的一部分(尽管可能不是Fortran)。 不可安装的libtool库,即用
noinst_LTLIBRARIES
声明的库,称为libtool便利库。那
noinst_
在建造的东西上有很大的不同。即使Libtool配置为构建共享库,libtool便利库实际上也不是共享库:它只是存储在存档中的一组目标文件(编译为PIC,以便后者可以在共享库中使用) 。您可以在任何地方使用libtool便利库,使用这组对象是有意义的,例如,构建共享库。 当多个libtool便利库被LIBADDed到可安装的libtool库(例如你的
libmain.la
)时,Libtool必须解压缩包含每个便利库对象的档案并将它们链接到最终库中。 这里有一个值得注意的陷阱:构建共享库时 便利库,如果
_SOURCES
变量为空Automake不知道使用哪个链接器,默认为C链接器。如果您想欺骗Automake使用某些特定语言的链接规则,您可以声明一个不必存在的
nodist_EXTRA_..._SOURCES
源文件。 (有关示例,请参阅Automake手册的Libtool Convenience Libraries部分。) 也许那是你的问题?如果您的某些模块的源代码中有一些Fortran文件(您的描述表明它们只是C文件),只有在为该libtool库声明的源文件中出现Fortran文件时,Fortran链接器才会用于构建
libmain.la
。当
libmain_la_SOURCES
为空时,将使用C链接器。 否则,我不知道它为什么不起作用。 您的示例中存在一个小错误:
libmain_la_LIBADD = $(top_srcdir)/src_module1/libmodule1.la
应该
libmain_la_LIBADD = $(top_builddir)/src_module1/libmodule1.la
因为库未在源目录中创建。但是我认为这只是一个错字,除非你做VPATH构建或运行
make distcheck
,否则你不会看到差异。 你的第二次尝试,使用不带Libtool的
_LIBRARIES
预计不起作用。
_LIBRARIES
只能用于声明静态存档,在这种情况下,
_LIBADD
可能只包含目标文件,而不包含其他静态存档。解压缩存档以将其对象重用到另一个存档中可能很难移植。 Automake对此问题的回答一直是:安装Libtool并使用
_LTLIBRARIES
(Libtool可以配置为仅构建静态库)。     

要回复问题请先登录注册