我正在转换一个C ++程序,该程序使用autotools构建系统来使用共享库,引入了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
但这不是官方消息来源。
答案 0 :(得分:8)
从不永远安装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
。
此类文件的目的地通常为glibconfig.h
。请参阅GLib for example,尽管他们会在没有模板的情况下生成configure.ac
(通过将AC_SUBST
内嵌的整个创建代码编写为the autobook suggests)。我发现这种方法比使用{{1}}更难维护,但它更灵活。
当然,为了帮助编译器找到依赖于平台的头文件,您可能还需要编写一个pkgconfig脚本,就像GLib一样。
答案 1 :(得分:1)
如果config.h
影响界面,则需要安装#define
。实际上,如果标题需要.cc
,而不仅仅是config.h
实现/编译单元。
如果AC_CONFIG_HEADERS([foo_config.h])
出现问题,您可以在AC_CONFIG_HEADERS宏中指定其他名称。例如,nodist_include_HEADERS = foo_config.h
。
假设automake,安装标头的最简单方法是:
Makefile.am
位于顶级nodist
。 foo_config.h
前缀告诉automake生成foo_config.h
而不是随包一起分发。
如果不使用automake,请在$includedir
中安装$exec_prefix/include
。对于生成的标头,config.h
可以说是一个更正确的位置,但实际上前一个位置没问题。
我避免使用CPPFLAGS
,将foo_CPPFLAGS
或AC_SUBST
中的相关定义与Makefile.am
一起传递给AC_SUBST
来构建源代码,或foo.h.in
} config.h
在配置时生成标头。很多{{1}}是测试生成的噪音。它需要更多的基础设施,但这是我更喜欢的。除非你对autotools感到满意,否则我不会推荐这种方法。