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

标签 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 这两个文件同名但源不同,目录不同。

此外,在输入配置后,我检查了 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) is created. unintended directory is created.



我在输入 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, (build fail)
/home/user/test/lib_sample (another source codes in here)



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/enhance/lib.c
void lib()
{
  printf("enhance hello\n");
}

最佳答案

我自己回答了这个问题。

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

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

解决方案 1

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


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

关于c - (automake, libtool) 在不同目录中使用相同的源文件名时,在 automake 中构建失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30732219/

相关文章:

c++ - 如何使用语言支持等进行 "light"构建的 GCC 修剪?

linux - 如何从源代码安装内核模块。制作过程中出错

makefile - make 期间缺少文件 (cholrl.a)

c - 动态地从文本文件中读取一行

c - 适合初学者的 c 中的多个 if 语句

c - 此函数如何计算二叉树中的节点数

C GTK通过ESC关闭后无法再次打开Dialog

android-studio - 如何在 Flutter 中使用同一个代码库进行不同屏幕/UI 开发和产品构建的单独构建

java - 如何在构建时验证 Ibatis XML 格式正确?

linux - Makefiles输出目录