我遇到的问题解决了。我发布此内容是为了就解决方案实际有效的原因寻求解释。我以前在这里得到了很好的反馈。
我有一个使用非常简单的构建系统的遗留代码库,我的项目是将其迁移到 Autotools 以进行定制,特别是构建共享库。主库是用 C 编写的,但也必须可从 Fortran 链接(用于遗留目的),并且在 F77 中与一些测试代码一起分发。作者将源代码组织成模块...
src_module1/
src_module2/
...
testc/
testf77/
他们lib/libmain.a
通过编译 src_*/ 目录中的代码并使用 ranlib 归档对象来构建库。
我的第一种方法是分别从每个 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 或共享库的问题,我尝试仅构建静态,基本上将全部.la
更改为. 同样的问题。然而,这一次,在尝试链接 libmain.a 本身时,注意到错误“ranlib:库警告:libmain.a 目录为空(库中没有目标文件成员定义全局符号)”。.a
_LTLIBRARIES
_LIBRARIES
我发现的解决方案似乎是一个 hack。我没有为任何 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 --- 那里会发生什么?关于静态和共享库的 Wikipedia 文章对我来说还不够详细。
我非常感谢为理解我冗长的问题所做的一切努力。