【问题标题】:Correct installation of config.h for shared library using autotools使用 autotools 为共享库正确安装 config.h
【发布时间】:2013-11-04 08:34:44
【问题描述】:

我正在将使用 autotools 构建系统的 C++ 程序转换为使用共享库,介绍 libtool 的使用。大部分程序功能都放在共享库中,由主程序加载,以便将来其他程序可以访问公共代码。

在整个程序和库源代码中,生成的自动标题 config.h 与通常的宏一起使用:

#if HAVE_CONFIG_H
# include <config.h>
#endif

在 configure.ac 中,我使用宏来生成它:

AC_CONFIG_HEADERS([config.h])

我的问题是,我是否需要安装 config.h 才能让其他人能够使用我的库,如果需要,这样做的适当方法是什么,是否应该重命名以避免冲突等?

我在这方面找到的最多信息在这里:

http://www.openismus.com/documents/linux/building_libraries/building_libraries#installingheaders

但这几乎不是官方来源。

【问题讨论】:

    标签: c++ shared-libraries autotools autoconf libtool


    【解决方案1】:

    永远不要永远安装 autoheader 的 config.h。

    库的用户最不需要的就是来自config.h 泄漏的宏的干扰。您的库可能有 HAVE_FOOBAR,但我的软件可能以禁用 foobar 的方式编译,因此 HAVE_FOOBAR 会破坏我的编译。

    AX_PREFIX_CONFIG macro from the archive 是一种解决方法,所有内容都带有前缀。

    更好的方法是创建一个模板文件(例如blargconfig.h.in),其中包含以下行:

    typedef @BLARG_TYPE@ blarg_int_t;
    
    @BLARG_RANDOM_INCLUDE@
    

    然后AC_SUBST()configure.ac中的那些变量:

    AC_SUBST(BLARG_TYPE, ["unsigned short"])
    AC_SUBST(BLARG_RANDOM_INCLUDE, ["#include <somerandomheader.h>"])
    

    然后将其列为输出文件:

    AC_CONFIG_FILES([Makefile
                     src/Makefile
                     ...
                     include/blargconfig.h])
    

    .h 文件应与nodist_include_HEADERS 一起列出; .h.in 文件将自动分发,因为它已在 AC_CONFIG_FILES 中列出。

    此类文件的目标通常是$libdir/packagename/include。请参阅GLib for example,尽管它们在没有模板的情况下生成glibconfig.h(通过在configure.ac 中内联编写整个创建代码,如the autobook suggests)。我发现这种方法比使用AC_SUBST 更难维护,但更灵活。

    当然,为了帮助编译器找到与平台相关的头文件,您可能还想编写一个 pkgconfig 脚本,就像 GLib 那样。

    【讨论】:

    • 谢谢,我很好奇autotools开发人员没有预料到整个过程,它一定经常出现。
    • @crobar 在对 14 个分发 config.h 的库的小型统计中,我看到其中 9 个对其进行了重命名,其中 4 个包含它。
    • compiler find the platform-dependent header you'll probably also want to write a pkgconfig script 你能说得更具体些吗?我想在现有库中搜索平台(配置)相关的头文件。
    • 我不确定我理解你的意思。您是在创建一个需要安装此类标头的库,还是您正在尝试查找此类标头?我提到的工具pkg-config 只是一种隐藏使用库所需的所有魔法的方法。试试man pkg-config,或谷歌。
    【解决方案2】:

    如果config.h 影响界面,您将需要安装它。实际上,如果标头需要 #define,而不仅仅是 .cc 实现/编译单元。

    如果config.h 有问题,您可以在AC_CONFIG_HEADERS 宏中指定另一个名称。例如,AC_CONFIG_HEADERS([foo_config.h])。

    假设automake,安装标头的最简单方法是:

    nodist_include_HEADERS = foo_config.h

    在顶级Makefile.am。 nodist 前缀告诉 automake foo_config.h 是生成的,而不是随包分发的。

    如果不使用 automake,请在 $includedir 中安装 foo_config.h。 $exec_prefix/include 可以说是生成标头的更正确位置,但实际上前一个位置很好。


    我避免使用config.h,通过将CPPFLAGS 或foo_CPPFLAGS 中的相关定义与AC_SUBST 一起传递给Makefile.am 用于源代码构建,或AC_SUBST 到foo.h.in 以在配置时生成标头.很多config.h 是测试产生的噪音。它需要更多的基础设施,但这是我更喜欢的。除非您对自动工具感到满意,否则我不会推荐这种方法。

    【讨论】:

    • 如果我只是更改名称,而不是 foo-config.h 中的实际定义,这可能会成为问题吗?
    • @crobar - 我不这么认为。 autoheader(或autoreconf)应该尊重AC_CONFIG_HEADERS名称以产生foo_config.h.in;并且配置应该使用这个模板来生成foo_config.h。
    • 我正在处理一个现有项目,它在整个项目中使用 nr_double_t 之类的东西来表示 config.h 中定义的 double。事实上,我已经意识到我的标题不需要这个。我会将您的答案标记为正确,但只需添加其他人可能对 m4 宏 AX_PREFIX_CONFIG_H 感兴趣,它还将配置文件中的所有定义更改为对您的项目来说是唯一的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 2011-03-11
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    相关资源
    最近更新 更多