【问题标题】:Using Autotools for a new shared library使用 Autotools 创建新的共享库
【发布时间】:2011-03-11 10:51:35
【问题描述】:

我想做的是创建一个名为libxxx 的新共享库,它链接到另一个名为libzzz 的共享库,这个共享库有一个独立的类似“pkg-config”的工具,假设它叫做“ zzz-config",它给出了使用 libzzz 时编译阶段所需的 cflags。 我想做的是:

  • 使用 automake、autoconf 等自动工具创建 configure/makefile 等;
  • 它必须使用上面引用的zzz-config 脚本;
  • 它必须为源生成自动依赖关系;
  • 它必须具有构建调试(无优化)和发布(有优化)构建的模式;
  • 源代码为 C++;
  • 它必须以共享库为目标;
  • 它必须读取src 目录的源代码并将编译后的文件放在另一个目录中

我已经阅读了几乎所有可用的 autotools 教程,但我无法找到一种方法来做到这一点,如果你能指出一些例子会非常友好。

谢谢!

【问题讨论】:

    标签: c++ gcc g++ shared-libraries autotools


    【解决方案1】:

    使用自动工具很容易做到这一点。需要注意的几点:libzzz 可能会提供一个宏来为您完成大部分工作。例如,glib 提供了一个名为 AM_PATH_GLIB_2_0 的宏,它与库一起安装,因此您只需在 configure.ac 中调用它。 (请注意,宏命名错误,因为它踩在 automake 的命名空间上,但这完全是另一个问题。)这是一个示例 configure.ac 和 Makefile.am 可以满足您的要求(有关调试和发布版本的说明,请参见下文):

    配置.ac:

    # -*- 自动配置 -*- # 使用 autoconf 处理此文件以生成配置脚本。 AC_PREREQ([2.66]) AC_INIT([libxxx], [0.0.0], [alice@bob.com]) AC_CONFIG_SRCDIR([libxxx.cc]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([外国]) LT_INIT AC_PROG_CXX # 检查库。 # 如果 libzzz 有一个 autoconf 宏,请使用它。否则: AC_PATH_PROG([ZZZ_CONFIG],[zzz-config],[none]) AS_IF([测试 x"$ZZZ_CONFIG" = xnone],[ AC_MSG_ERROR([zzz-config not found in PATH]) ]) CPPFLAGS="$CPPFLAGS $(zzz-config -cflags)" LIBS="$(zzz-config -libs) $LIBS" # 完全没有必要:我们没有链接 # 如果找到 zzz-config,我们大概可以假设 # libzzz 已安装,但仍需检查: AC_CHECK_LIB([zzz],[main],[],[AC_MSG_ERROR([需要libzzz])]) # 检查头文件。 AC_CHECK_HEADERS([zzz.h]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT

    Makefile.am

    lib_LTLIBRARIES = libxxx.la libxxx_la_SOURCES = libxxx.cc include_HEADERS = xxx.h libxxx_la_LDFLAGS = -版本信息 0:0:0

    在进行调试或发布构建方面,有很多方法可以使用根本不涉及编辑构建脚本的自动工具来做到这一点。执行此操作的规范方法是在调用 configure 时设置 CXXFLAGS(例如,将 CXXFLAGS=-O2 CPPFLAGS=-DNDEBUG 作为参数传递给 configure 以获得发布版本)。您还可以设置您的系统,以便通过将这些分配写入 /usr/local/share/config.site 来将您安装在 /usr/local 中的所有内容作为发布版本,而为安装在 $HOME 中的所有内容将成为调试版本通过将 'CXXFLAGS="-g -O0"' 写入 $HOME/share/config.site。如果您想在配置时为用户提供 --disable-assert 选项以关闭断言,则可以在 configure.ac 中调用 AC_HEADER_ASSERT(但用户将 -DNDEBUG 放入 CPPFLAGS 中确实很容易)。您可以做的另一件好事是利用 automake 的 VPATH 构建来配置不同的构建目录,每个目录都进行了适当的配置。

    但是,如果您真的觉得需要将功能添加到构建脚本中,您可以尝试在 configure.ac 中添加类似的内容:

    AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug], [配置调试版本]), [CXXFLAGS="$CXXFLAGS -g -O0"]) AC_ARG_ENABLE([release],AS_HELP_STRING([--enable-release], [配置发布版本]), [CPPFLAGS="$CPPFLAGS -DNDEBUG"] [CXXFLAGS="$CXXFLAGS -O2"])

    请注意,这是可靠的,可能会导致用户混淆。例如,如果用户使用 config.site 将 CPPFLAGS 设置为 -DDEBUG 但调用了 --enable-release,则 CPPFLAGS 将包含“-DDEBUG -DNDEBUG”。如果您尝试完全重置 CPPFLAGS 以响应 --enable-release,则 libzzz 所需的 -I 标志将丢失。您可以通过 AC_SUBST'ing LIBZZZ_CFLAGS 并修改 Makefile.am 来避免最后一个问题,但教育您的用户在调用 configure 时设置 CPPFLAGS 和 CXXFLAGS 确实更容易。

    在我的回答中查看更多信息:https://stackoverflow.com/a/4680578/140750

    【讨论】:

      【解决方案2】:

      我也会远离自动工具。

      同样,我在 Cmake 方面的经验也不尽如人意。事情可能已经改变了,但是当我不久前试图学习它时,文档却没有。

      我倾向于使用 scons:http://www.scons.org/

      也就是说,我不知道它在大型项目(即数千个或更多文件)上的表现如何。不过,对于中小型项目来说,这很好。

      您也可以尝试 qmake,但我只建议您使用 Qt。

      【讨论】:

        【解决方案3】:

        我的建议是使用CMake 而不是autotools。它更容易使用,它还可以创建依赖于平台的项目来使用(即基于 Makefile 的项目、Visual Studio 项目、Eclipse CDT 项目等)。

        它还将创建debugrelease 项目,具体取决于CMAKE_BUILD_TYPE 变量值。

        创建libxxx 库非常简单:

        add_library(libxxx SHARED ${LIBXXX_SOURCES})
        

        其中LIBXXX_SOURCES 是一个保存源的变量。

        链接这两个库同样简单(参见target_link_libraries):

        target_link_libraries(libxxx libzzz)
        

        要从zzz-config 脚本中获取编译标志,您可以使用execute_process 命令,如下所示:

        execute_process(COMMAND ./zzz-config 
                        WORKING_DIRECTORY "<your_working_directory>"
                        OUTPUT_VARIABLE ZZZ_FLAGS)
        

        然后您可以设置CMAKE_C_FLAGSCMAKE_CXX_FLAGS 变量来设置所需的编译标志。

        【讨论】:

        • 感谢您的回答,我不知道 CMake 已经拥有所有这些引用的功能,太棒了 =)
        • 不客气 :) 除了官方文档和在线教程,我推荐你阅读一本很棒的书。它被称为Mastering Cmake,它讨论了许多其他有用的cmake 功能。
        猜你喜欢
        • 2013-08-15
        • 1970-01-01
        • 2013-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多