5

我们研究组的部分程序具有ctemplate库提供的辅助功能。在我们过时的集群上,由于编译,我们无法构建软件,所以我想分离这个功能并通过一个标志来控制它是否包含configure,例如--disable-ctemplate.

该软件是用 C++ 编写的,使用 Autotools 构建系统——我对这两个系统都没有太多经验。我的理解是,要完成这个任务,我需要做到以下几点:

  1. 通过AC_ARG_ENABLEconfigure.ac.

  2. 围绕使用该库的代码以及调用该代码的任何代码添加一些#ifdef(或可能的)语句。#ifndefctemplate

我认为第一步看起来像这样:

AC_ARG_ENABLE(ctemplate,
[  --disable-ctemplate    Disable HTML output],
[case "${enableval}" in
  yes) ctemplate=false ;;
  no)  ctemplate=true ;;
  *) AC_MSG_ERROR(bad value ${enableval} for --disable-ctemplate) ;;
esac],[ctemplate=true])
AM_CONDITIONAL(NOCTEMPLATE, test x$ctemplate = xfalse)

虽然我不知道逻辑是否正确,因为我已经从使用--enable-FLAG而不是--disable-FLAG.

对于第二步,我将把部分包装在预处理器标志中,例如

#ifndef NOCTEMPLATE
void Class::MethodUsingCtemplate(...)
{
    ...
}
#endif

如果我这样做了,这会正确地“连接”一切configure --disable-ctemplate吗?

另外,这样能保证程序不进入ctemplate库编译吗?如果没有,那么这一切都是徒劳的;我必须阻止ctemplate库和依赖组件的编译。

我将重申我对 C++ 和 Autotools 都不熟悉;我采取了一种非常幼稚的第一种方法来解决这个问题。如果您在这方面有经验,我非常感谢您的更正和您可以提供的任何解释。

4

2 回答 2

6

这是我在阅读文档、教程、帮助线程、邮件列表等之后汇总的解决方案,并且只是简单地尝试一些事情直到它们起作用,我可以解释它们为什么起作用。

configure.ac中,我放置了以下代码行

# This adds the option of compiling without using the ctemplate library,
# which has proved troublesome for compilation on some platforms
AC_ARG_ENABLE(ctemplate,
  [ --disable-ctemplate   Disable compilation with ctemplate and HTML output],
  [case "${enableval}" in
     yes | no ) WITH_CTEMPLATE="${enableval}" ;;
     *) AC_MSG_ERROR(bad value ${enableval} for --disable-ctemplate) ;;
   esac],
  [WITH_CTEMPLATE="yes"]
)

dnl Make sure we register this option with Automake, so we know whether to
dnl descend into ctemplate for more configuration or not
AM_CONDITIONAL([WITH_CTEMPLATE], [test "x$WITH_CTEMPLATE" = "xyes"])

# Define CTEMPLATE in config.h if we're going to compile against it
if test "x$WITH_CTEMPLATE" = "xyes"; then
    AC_DEFINE([CTEMPLATE], [], ["build using ctemplate library"])
    AC_MSG_NOTICE([ctemplate will be used, HTML output enabled])
else
    AC_MSG_NOTICE([ctemplate will not be used, HTML output disabled])
fi

在下一步中,我将Makefile.am顶层更改为以下内容:

if WITH_CTEMPLATE
  MAYBE_CTEMPLATE = ctemplate
endif

SUBDIRS = boost libgsl $(MAYBE_CTEMPLATE) libutil ...

在较低级别Makefile.am的s中,我添加了

if WITH_CTEMPLATE
    # some change to the configuration
else
    # some other change to the configuration
endif

最后,我必须确保关键的 C++ 头文件之一(包含在代码的其他部分中)具有以下内容:

#ifdef HAVE_CONFIG_H
#    include "config.h"
#endif

config.h包含使用 创建的任何新定义AC_DEFINE,因此该文件必须包含在检查此路由创建的宏定义是否已定义(或未定义)的部分中。

这花费了我很多时间并克服了我的挫败感。我只能希望在这里记录这个解释可以让其他人免于同样的命运。

于 2009-08-23T23:18:55.970 回答
1

为了防止构建尝试在 ctemplate 子目录中编译,您需要执行以下操作:

如果 CTEMPLATE
子目录 += ctemplate
万一

在 Makefile.am

于 2009-08-18T19:00:30.607 回答