我有一个目前使用通信库进行通信的项目。该库不是通用的;它只能在某些机器上运行。我想移植我的项目,以便能够使用其他库进行通信。为此,我定义了一个具有不同实现的抽象层。这些实现由几个文件组成,因此我想将它们分组到不同的文件夹中。
例如,我可能有一个使用tcp的实现,另一个使用一些系统本机库进行通信。我的tcp
文件夹中有一个文件夹native
和一个文件夹src
。我希望autotools使用在配置时使用--with-comm=XXX
选择的一个实现。
如何构建Makefile.am来实现这一目标?我读过这个:Different implementations in different files in autotools, 但是那个只使用不同的文件用于不同的实现,但我想使用文件夹。
答案 0 :(得分:2)
您可以使用configure.ac
中的AC_ARG_WITH
宏,但更适合将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
变量中。虽然这应该有用,但它并不是“正确的”。如何去做事......
正确的库应该在src
中构建,这意味着在tcp
或native
中使用便捷库,让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.
这是一种更具前瞻性的方法,作为您的核心'和'层'图书馆变得更加复杂 - 他们会:)