Search code examples
c++makefileautotoolsautoconfautomake

Cannot totally compile and link cpp project as a static library


I have followed this link and adapted its steps to make it work for my project.

My goal is to create a libfile.a to distribute as a static library. The project tree is the following:

project
   |
   +-src
      +- <some cpp and hpp files>
      |
      + containers
             |
             +- <other cpp and hpp files>

I easily created configure.ac file and the Makefile.ams. The tree structure changed this way:

project
   |
   +- configure.ac
   +- Makefile.am
   +-src
      +- <some cpp and hpp files>
      + Makefile.am
      |
      + containers
             |
             +- <other cpp and hpp files>

Now, when I go: (*)

aclocal; autoreconf --install; autoconf; ./configure
make

.o files are generated for all the .*pp files contained in src, but it fails when it starts generating those targets in src/containers. So the Makefile is not generated properly. What am I doing wrong? Can someone help me?

PS here there are files involved:

# --- configure.ac ---

AC_PREREQ([2.68])
AC_INIT([filea], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([filea], [1.0])
AC_CONFIG_SRCDIR([src/HashFunctions.cpp])
AC_CONFIG_HEADERS([config.h])

AC_PROG_CXX
AC_PROG_RANLIB

AC_CHECK_HEADERS([stddef.h stdint.h string.h])
AC_HEADER_STDBOOL

AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT8_T

AC_FUNC_MALLOC
AC_FUNC_MKTIME
AC_CHECK_FUNCS([memset])

AC_OUTPUT([Makefile src/Makefile])

# --- Makefile.am ---

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src


# --- src/Makefile.am ---

lib_LIBRARIES = libfile.a
libfile_a_SOURCES = \
    ConfigLib.hpp \
    ConfigLib.cpp \
    HashFunctions.cpp \
    HashFunctions.hpp \
    Logger.hpp \
    Logger.cpp \
    Queue.hpp

libfile_a_SOURCES += \
    containers/SafeContainer.cpp \
    containers/SafeInterger.cpp \
    containers/SafeMap.cpp

EDIT 1 as suggested by Brett Hale the commands marked with (*) have been replaced by the following ones:

autoreconf -fvi

Output:

autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force 
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
autoreconf: Leaving directory `.'

When going with:

./configure
make

Still no rules are found to generate targets in the subdirectory.

EDIT 2 I switched to a non-recursive approach (Thanks to Karel Zak's blog) and finally I can makemy lib.


Solution

  • Still I don't know what I was doing wrong following the typical recursive approach; but, finally I made this work, switching to a non-recursive approach (as I wrote in EDIT 2). This article on Karel Zak's Blog helped me a lot!

    # -- new configure.ac file --
    AC_PREREQ([2.68])
    AC_INIT([filea], [1.0], [[email protected]])
    AM_INIT_AUTOMAKE([filea], [1.0])
    AC_CONFIG_HEADERS([config.h])
    AC_CONFIG_SRCDIR([src/HashFunctions.cpp])
    
    AM_INIT_AUTOMAKE([filea], [1.0])
    LT_INIT
    
    AC_CANONICAL_HOST
    AC_PROG_LIBTOOL
    AC_PROG_GREP
    AC_PROG_EGREP
    AC_PROG_CXX
     ...
    AC_HEADER_STDBOOL
    AC_C_INLINE
    AC_TYPE_PID_T
    AC_TYPE_SIZE_T
    AC_TYPE_SSIZE_T
    AC_TYPE_UINT8_T
    AC_TYPE_UINT16_T
    AC_TYPE_UINT32_T
    
    AC_FUNC_ERROR_AT_LINE
    AC_FUNC_FORK
    AC_FUNC_MALLOC
    AC_FUNC_MKTIME
    AC_CHECK_FUNCS([memset socket])
    
    AC_OUTPUT([Makefile]) # the makefile is only one!
                          # In the subdirectory I have created few
                          # Makemodule.am included in the "main makefile.am"
    
    # --- makefile.am ---
    AUTOMAKE_OPTIONS = foreign
    lib_LIBRARIES = filea.a
    
    libfilea_a_SOURCES =
    include src/Makemodule.am
    include src/containers/Makemodule.am # now filea_a_SOURCES is a
                                         # "global variable"
    # -- src/Makemodule.am
    libfilea_a_SOURCES += \
        src/ConfigLib.hpp \
        src/ConfigLib.cpp \
        src/HashFunctions.cpp \
        src/HashFunctions.hpp \
        src/Logger.hpp \
        src/Logger.cpp \
        src/Queue.hpp
    
    # -- src/containers/Makemodule.am
    libfile_a_SOURCES += \
        src/containers/SafeContainer.cpp \
        src/containers/SafeInterger.cpp \
        src/containers/SafeMap.cpp
    

    Notice that now, even if Makemodule.am files are placed at different levels in the dir tree, whenever a filename is typed in one those modules, it has to be preceded by its relative path. This path is relative to Makefile location.