0

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

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

  1. 从图书馆维护的角度来看,这里的正确方法是什么?
  2. 在公共标头中使类型或函数可选的正确方法是什么?

最初,我认为我应该将标头转换为 autoconf 输入 (.in) 文件,并生成标头,并选择删除这些函数和类型。

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

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

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

4

2 回答 2

1

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

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

但是我不喜欢第二种方法,因为这意味着 configure 必须在 mylib.h.in 更改时重新运行。

于 2012-02-25T09:36:50.220 回答
0

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

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

于 2012-02-27T19:32:41.737 回答