(automake, libtool) build fails in automake when using same source file name in different directory

2.2k views Asked by At

OS: Ubuntu 14.14
automake version: automake (GNU automake) 1.14.1

I build source codes to make a shared library by using automake. But I got a error that automake may can't handle source codes which are same name and different directory. Can't I compile the same file name source codes in different directory by using automake?

For instance, lib_sample/lib.c, lib_sample/enhance/lib.c those two files are the same name but different source and different directories.

Also, After typing the configure, I check the src directory, weird directory($(LIB_DIR)) is created.

./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.

I got an error message when I type the make command.

the error message looks like this.

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

First problem is, after configure script, the $(LIB_DIR) directory is created.

Second problem is a failure in build source codes when I type the make command. I think the libtool fail to compile when it tries to make .Plo files, but what I can't understand is that why automake tries to compile lib_sample/src/lib.c. Because I denote the LIB_DIR path with --with-lib and --enable-enhance option, before compiling the sources in ./configure script. Therefore, automake should do not manage src/lib.c. However, automake tries to compile lib_sample/src/lib.c and the strange message comes out.

You can see codes how I write below, and project structures in detail.

Thanks in advance.

Here in details.

There are two directories.

/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

top directory 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

run configure command before make

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

the error message when I type the '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 directory structure (same file name in different directory)

/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");
}
1

There are 1 answers

0
김지욱 On

I answered this myself.

According to the reference(http://www.gnu.org/software/automake/manual/html_node/Conditional-Sources.html), a user specified variable, $(LIB_DIR) in this case, can't be used in a _SOURCES variable. However, it works fine in my case except when the variable is used with same file name and if statement. The problem is that the variable which user specified is used in a _SOURCES variable and if statement with same file name.

So, I thought there are two possible solutions. One is that I may change a file name one of them to avoid using same file name. Another is that using a variable represents 'enhance' string, which is the directory name, to remove if statement in Makefile.am.

Solution 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

But, I can't change the file name, the reason for this is a bit hard to explain, in short to speak, because of source code permission.

Solution 2

I solved the problem in this way.

part of 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