Search code examples
c++linuxautomakelibtool

How a c++ program (.cpp) work with header(.h) and libtool (.la)?


I have create a folder in linux called helloworld. Inside this folder have sub-directory:

  • include
  • lib
  • src

include/ In this directory I have create a header file called helloworld.h content are:

class helloworld{
public:

       void getvalue();

};

lib/ In lib directory I have create a cpp file called helloworld.cpp content are mainly functions:

#include<iostream>
#include<helloworld.h>
using namespace std;

void helloworld::getvalue() {

}

src/ In src directory I have create a main cpp file called main.cpp content are main:

#include<iostream>
#include<helloworld.h>

int main()
{
helloworld a;
a.getvalue();
}

but after I autoconf, automake, ./configure, and when make it has a error:

helloworld/src/main.cpp:8: undefined reference to `helloworld::getvalue()'

All I want is to use helloworld.cpp's functions in main.cpp. I've spend a lot of time searching and try and error. Please help.

Added the Makefiles.am

in parent directory, I have two files Makefile.am and configure.ac:

Makefile.am

AUTOMAKE_OPTIONS = foreign
SUBDIRS=src lib

configure.ac

AC_INIT([helloworld], [0.1], [[email protected]])
AM_INIT_AUTOMAKE
AC_PROG_RANLIB
AC_LANG(C++)
AC_PROG_CC
AC_PROG_CXX
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_LIBTOOL
AC_DISABLE_STATIC
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
AC_SUBST([CC])
LT_INIT
AC_OUTPUT

In lib directory has one Makefile.am

INCDIR=../include
INCPATH=-I. -I$(INCDIR)
AM_CPPFLAGS=$(INCPATH)
lib_LTLIBRARIES=libhelloworld.la
libhelloworld_la_SOURCES=helloworld.cpp

In src directory has one Makefile.am

INCDIR=../include
INCPATH=-I. -I$(INCDIR)
AM_CPPFLAGS=$(INCPATH)
helloworld_LDADD=-L/lib/libhelloworld.la
bin_PROGRAMS=helloworld
helloworld_SOURCES=main.cpp

Compiled success if I take out the a.getvalue();


Solution

  • If you insist on using recursive make, you will need to add a special rule to src/Makefile.am to make sure the lib/Makefile.am rules for rebuilding the library are applied (untested here, but used in other projects).

    This now means that a normal recursive build will build ., include, lib, src, and then lib again. I would strongly recommend ditching recursive make and use the one Makefile.am solution I have laid out in my other answer.

    bin_PROGRAMS        = helloworld
    helloworld_CPPFLAGS = $(top_srcdir)/include
    helloworld_LDADD    = $(top_builddir)/lib/libhelloworld.la
    helloworld_SOURCES  = main.cpp
    
    $(top_builddir)/lib/libhelloworld.la:
            cd $(top_builddir)/lib && $(MAKE) libhelloworld.la