1

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

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

我如何构建 Makefile.am 来实现这一点?我读过这个:在 autotools 中的不同文件中的不同实现,但是对于不同的实现只使用不同的文件,但我想使用文件夹。

4

1 回答 1

2

您可以使用 in 中的AC_ARG_WITHconfigure.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通过条件变量进行设置会很好,但是AFAIK这不起作用。此外,tcp如果native您使用make dist. 没有必要将任何一个放在EXTRA_DIST列表中,但如果可选“层”的数量变得笨拙,这可能是一个更好的方法。


如果我正确理解您的评论,那么简单的方法是将src文件包含在子目录构建中,因此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.h,wrapper.c等添加到其EXTRA_DIST变量中。虽然这应该可行,但这不是处理事情的“正确”方式......


适当的库应该是内置的,这意味着在orsrc中使用便利库,其余的不用担心。例如:tcpnativelibtoolsrc/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.

这是一种更面向未来的方法,因为您的“核心”和“层”库变得更加复杂 - 他们会:)

于 2013-06-27T17:03:17.290 回答