使用automake处理库的可选公共类型/函数的正确方法是什么?

时间:2012-02-25 02:56:04

标签: autotools autoconf automake libtool

在我维护的库中,有一些函数依赖于pthread。该项目使用automake。我想创建一个配置选项来禁用对pthreads的依赖,这不应该编译那些函数。 (原因是某些交叉编译和嵌入目标。)

避免编译包含这些函数的文件到目前为止工作正常,但现在我意识到这些函数和它们使用的一个结构都是在公共头文件中定义的。

  1. 从图书馆维护的角度来看,这里的正确方法是什么?
  2. 在公共标题中使类型或函数可选的正确方法是什么?
  3. 最初我认为我应该将标题转换为autoconf输入(.in)文件,并生成包含这些函数和类型的标题,可选择删除。

    但是,那么可能同时安装了不同版本库的系统呢?通常这些应该能够共享标题。

    我是否应该使用预处理器条件来避免这些函数,并使用pkg-config将其指定为命令行选项?

    另一个想法是将这些函数和类型移动到它们自己的头文件中,并避免在禁用pthreads时安装此头文件。这意味着稍微搞乱标题的组织,但也许是最好的主意。我想要你的意见,在图书馆的公共标题中处理可选功能的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

一种方法是让您的需要线程的函数继续在嵌入式平台上存在,但是在它们被调用时返回错误代码。这样,API在各个平台上保持不变,这对于使用您的库(“程序”)的代码来说是非常理想的,因为程序不需要类似于autoconf的测试来存在库中的函数,但可以使用它们并利用源代码级别来确定其功能。

int mylib_thread_frenzy(void)
{
#ifdef HAVE_PTHREAD_CREATE
       int ret = pthread_create(...);
       if (ret < 0)
               return -errno;
       return 0;
#else
       return -ENOSYS;
#endif
}

/* Program */
int ret = mylib_thread_frenzy();
if (ret == -ENOSYS) {
    /* Hm, castrated platform. Try something else... */
    printf("Or just tell the user the platform is too weak.\n");
} else {
    printf("World domination acquired\n");
}

在任何情况下,不要尝试在mylib.h中#include“config.h”,也不要发送此config.h,因为config.h中提出的定义可能与另一个库中的定义冲突和/或程序。

如果你绝对想从mylib.h中删除函数,我想这会想到:

/* mylib.h.in */
#if 0@HAVE_PTHREAD_CREATE@
extern int mylib_pthread_frenzy(void);
#endif

/* configure.ac */
AC_SEARCH_LIBS([pthread_create], [pthread],
  [HAVE_PTHREAD_CREATE=1
   AC_SUBST([HAVE_PTHREAD_CREATE])
  ])
AC_CONFIG_FILES([mylib.h.in])
AC_OUTPUT

但是我不喜欢第二种方法,因为这意味着每当mylib.h.in发生变化时,都必须重新运行。

答案 1 :(得分:0)

  

另一个想法是将这些函数和类型移动到它们自己的头文件中,并避免在禁用pthreads时安装此头文件。

这是最干净的选择。当您通过AC_ARG_ENABLE启用该选项时,您也可以绕过所有pthread设置。使用此选项,依赖于库的包将能够轻松地(通过AC_TRY_COMPILE)告诉pthread可选函数不存在而不是AC_TRY_RUN,以查看这些函数是否在运行时工作。 / p>