(automake,libtool)在不同目录中使用相同的源文件名时,在automake中构建失败

时间:2015-06-09 12:36:16

标签: c build makefile automake libtool

操作系统:Ubuntu 14.14
automake版本:automake(GNU automake)1.14.1

我使用automake构建源代码以创建共享库。 但是我得到一个错误,因为automake可能无法处理同名和不同目录的源代码。 我不能使用automake?

在不同的目录中编译相同的文件名源代码

例如,lib_sample / lib.c,lib_sample / enhance / lib.c这两个文件名相同但源和目录不同。

此外,在输入configure之后,我检查了src目录,创建了奇怪的目录($(LIB_DIR))。

  

./ configure --with-lib = / home / user / workspace / lib_sample --enable-enhance
  ls src /
  $(LIB_DIR)Makefile Makefile.am Makefile.in mod_sample.c
   - > $(LIB_DIR)已创建。创建了非预期的目录。

当我输入make命令时收到错误消息。

错误消息如下所示。

Makefile:423: /src/.deps/lib.Plo: No such file or directory
Makefile:424: /src/enhanced/.deps/lib.Plo: No such file or directory
make[1]: *** No rule to make target `/src/enhanced/.deps/lib.Plo'.  Stop.
make[1]: Leaving directory `/home/user/test/mod_sample/src'
make: *** [all-recursive] Error 1

第一个问题是,在配置脚本之后,创建了$(LIB_DIR)目录。

第二个问题是当我输入make命令时构建源代码失败。 我认为libtool在尝试生成.Plo文件时无法编译,但我无法理解的是为什么automake尝试编译lib_sample / src / lib.c。 因为我在编译./configure脚本中的源代码之前用--with-lib和--enable-enhance选项表示LIB_DIR路径。因此,automake不应该管理src / lib.c. 但是,automake尝试编译lib_sample / src / lib.c并发出奇怪的消息。

您可以看到我在下面编写的代码,以及详细的项目结构。

提前致谢。

详细说明。

有两个目录。

  

/ home / user / test / mod_sample,(构建失败)
  / home / user / test / lib_sample(这里有另一个源代码)

configure.ac(/home/user/test/mod_sample/configure.ac)

dnl Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)
AC_INIT(sample, 1.5.0)
AC_PROG_CC
AC_PROG_CXX

AC_CANONICAL_SYSTEM

AM_INIT_AUTOMAKE([subdir-objects])

AM_PROG_CC_C_O

LT_INIT

AC_PROG_LIBTOOL

AC_MSG_CHECKING(--with-lib)
AC_ARG_WITH([lib],
AC_HELP_STRING([--with-lib=DIR], [Set lib path ]),
    [LIB_DIR=$withval]
    [have_lib=yes],
    [have_lib=no])
AC_MSG_RESULT($LIB_DIR)
AC_SUBST(LIB_DIR)

AC_ARG_ENABLE([[enhance]],
  [AS_HELP_STRING([[--disable-enhance]], [enhance])], ,
  [enable_enhance=yes])
  test "x$enable_enhance" = "xno" || enable_enhance=yes
AM_CONDITIONAL([HAVE_ENHANCE], [test "x$enable_enhance" = "xyes"])

AC_CONFIG_FILES(Makefile
          include/Makefile
          src/Makefile)
AC_OUTPUT

顶级目录Makefile.am(/home/user/test/mod_sample/Makefile.am)

SUBDIRS=src include

src / Makefile.am(/home/user/test/mod_sample/src/Makefile.am)

lib_LTLIBRARIES = libmod_sample.la
libmod_sample_la_SOURCES = mod_sample.c

if HAVE_ENHANCE
    libmod_sample_la_SOURCES+=$(LIB_DIR)/src/enhanced/lib.c
else
    libmod_sample_la_SOURCES+=$(LIB_DIR)/src/lib.c
endif

在make

之前运行configure命令
  

autoreconf -if
  ./configure --with-lib = / home / user / workspace / lib_sample --enable-enhance

输入'make'时的错误消息。

Makefile:423: /src/.deps/lib.Plo: No such file or directory
Makefile:424: /src/enhanced/.deps/lib.Plo: No such file or directory
make[1]: *** No rule to make target `/src/enhanced/.deps/lib.Plo'.  Stop.
make[1]: Leaving directory `/home/user/test/mod_sample/src'
make: *** [all-recursive] Error 1

lib_sample目录结构(不同目录中的文件名相同)

  

/home/user/workspace/lib_sample/lib.c
  /home/user/workspace/lib_sample/enhance/lib.c

lib_sample / lib.c

void lib()
{
  printf("hello\n");
}

lib_sample /增强/ lib.c

void lib()
{
  printf("enhance hello\n");
}

1 个答案:

答案 0 :(得分:2)

我自己回答了这个问题。

根据引用(http://www.gnu.org/software/automake/manual/html_node/Conditional-Sources.html),在这种情况下,用户指定的变量$(LIB_DIR)不能用于_SOURCES变量。但是,它在我的情况下工作正常,除非变量使用相同的文件名和if语句。问题是用户指定的变量用于_SOURCES变量和if语句具有相同的文件名。

所以,我认为有两种可能的解决方案。一个是我可以更改其中一个文件名以避免使用相同的文件名。另一个是使用变量表示增强' string,这是目录名,用于删除Makefile.am中的if语句。

解决方案1 ​​

  

mv lib_sample / enhance / lib.c lib_sample / enhance / lib_enhance.c
  使

lib_LTLIBRARIES = libmod_sample.la
libmod_sample_la_SOURCES = mod_sample.c

if HAVE_ENHANCE
    libmod_sample_la_SOURCES+=$(LIB_DIR)/src/enhanced/lib_enhance.c # change the file name
else
    libmod_sample_la_SOURCES+=$(LIB_DIR)/src/lib.c
endif

但是,我无法更改文件名,因为源代码许可,其原因很难解释,简而言之。

解决方案2

我以这种方式解决了这个问题。

configure.ac的一部分(/home/user/test/mod_sample/configure.ac)

AC_ARG_ENABLE([[enhance]],
  [AS_HELP_STRING([[--disable-enhance]], [enhance])], ,
  [enable_enhance=yes])
  test "x$enable_enhance" = "xno" || enable_enhance=yes
AM_CONDITIONAL([HAVE_ENHANCE], [test "x$enable_enhance" = "xyes"])
AM_COND_IF([HAVE_ENHANCE], [AC_SUBST(ENHANCE, "enhance")], [AC_SUBST(ENHANCE, "")]) # Add this line

src / Makefile.am(/home/user/test/mod_sample/src/Makefile.am)

lib_LTLIBRARIES = libmod_sample.la
libmod_sample_la_SOURCES = mod_sample.c

# Use $(ENHANCE) variable to remove if statement
# $(ENHANCE) can be "enhance" or empty string.
libmod_sample_la_SOURCES+=$(LIB_DIR)/src/$(ENHANCE)/lib.c