c - 如何告诉自动工具在不同的文件夹中使用不同的实现

标签 c autotools automake

我有一个项目目前使用通信库进行通信。该库不是通用的;它只在某些机器上运行。我想移植我的项目以便能够使用其他库进行通信。为此,我定义了一个具有不同实现的抽象层。这些实现由多个文件组成,因此我想将它们分组到不同的文件夹中。

例如,我可能有一个使用 tcp 的实现,另一个使用一些系统 native 库进行通信。我的 src 文件夹中有一个文件夹 tcp 和一个文件夹 native 。我希望自动工具使用一种在配置时通过 --with-comm=XXX 选择的实现。

如何构建 Makefile.am 来实现这一点?我读过这个:Different implementations in different files in autotools , 但是那个只针对不同的实现使用不同的文件,但我想使用文件夹。

最佳答案

您可以使用 AC_ARG_WITH configure.ac 中的宏,但使用 AC_ARG_ENABLE 更合适用于内部编译时功能。例如,在 configure.ac 中:

AC_ARG_ENABLE([comm], [AS_HELP_STRING([--enable-comm[[=tcp]]],
                  [specify a communications layer (default=tcp)])],
              , [enable_comm=yes])

enable_comm=`echo $enable_comm` # strip whitespace.

if test "x$enable_comm" = "xyes" || "x$enable_comm" = "xtcp" ; then
  enable_tcp="yes"
elif test "x$enable_comm" = "xnative" ; then
  enable_native="yes"
elif test "x$enable_comm" = "xno" ; then
  ; # ... error message? default to a dummy layer implementation?
else
  AC_MSG_ERROR([unknown option: '$enable_comm' for --enable-comm])
fi

AM_CONDITIONAL([ENABLE_COMM_TCP], [test "x$enable_tcp" = "xyes"])
AM_CONDITIONAL([ENABLE_COMM_NATIVE], [test "x$enable_native" = "xyes"])
...
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([src/tcp/Makefile src/native/Makefile])
...
AC_OUTPUT

当然,您可以在帮助字符串中放入任何您喜欢的内容,并设置不同的默认值。

src/Makefile.am 中:

if ENABLE_COMM_TCP
COMM_DIR = tcp
endif

if ENABLE_COMM_NATIVE
COMM_DIR = native
endif

SUBDIRS = . $(COMM_DIR) # or '$(COMM_DIR) .' for depth-first order.

由于 automake 的工作方式,存在一些限制。能够通过条件变量设置 COMM_DIR 会很好,但据我所知这是行不通的。此外,如果您使用 make dist,此方法会在分发中自动包含 tcpnative 文件夹。无需将两者都放在 EXTRA_DIST 中列表,但如果可选“层”的数量变得笨重,这可能是更好的方法。


如果我正确理解了您的意见,那么简单的方法是将 src 文件包含在子目录 build 中,这样 src/tcp/Makefile.am 就会使用:

lib_LTLIBRARIES = libcomm.la
libcomm_la_SOURCES = driver.h driver.c ../comm.h ../wrapper.c ...

如果 comm.h 需要指定为 $(srcdir)/../comm.h 用于树外构建,我不记得了才能正常工作。 src/Makefile.am 可能需要也可能不需要将 comm.hwrapper.c 等添加到其 EXTRA_DIST 变量。虽然这应该可行,但这不是处理事情的“正确”方法......


适当的库应该在 src 中构建,这意味着在 tcpnative 中使用方便的库,并让 libtool 担心剩下的。例如,src/Makefile:

lib_LTLIBRARIES = libcomm.la
libcomm_include_HEADERS = comm.h
libcomm_la_SOURCES = comm.h wrapper.c utils.c ...
libcomm_la_LIBADD = ./$(COMM_DIR)/libcomm_layer.la

还需要订购:SUBDIRS = $(COMM_DIR) 。

src/tcp/Makefile.am

AM_CPPFLAGS += -I$(srcdir)/.. # look for core headers in src

noinst_LTLIBRARIES = libcomm_layer.la # not for installation.
libcomm_layer_la_SOURCES = driver.h driver.c ...
# libcomm_layer_la_LDFLAGS = -static # optional... an archive is preferable.

随着您的“核心”和“层”库变得越来越复杂,这是一种更具前瞻性的方法 - 它们将会:)

关于c - 如何告诉自动工具在不同的文件夹中使用不同的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17347970/

相关文章:

我可以在自己的C程序中捕获Linux程序执行的系统调用吗?

autotools - 使用 automake 配置脚本在 64 位 Linux 上构建 32 位?

c++ - 生成文件.am : How to Add rule for new extension?

c++ - Python 嵌入 C++

unit-testing - 制作需要输入文件的 distcheck 和测试

objective-c - Xcode & 网页 View : Load local html if no internet connection (fallback)

c++ - 奇怪的 GCC 优化错误

c - 这在c中是什么意思?大括号内的方括号

c++ - Autotools 将库标志添加到 ar

windows - `Jam` 可以用作带有 autoconf 的 GNU Make 的替代品吗?