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

不想你离开。 提交于 2020-07-10 07:29:50

问题


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], [helloworld@gmail.com])
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();


回答1:


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



回答2:


helloworld_LDADD=-L/lib/libhelloworld.la


/lib/libhelloworld.la  

this search lib from root directory not your project lib/ directory

Try

./lib/libhelloworld.la

or

../lib/libhelloworld.la

or

lib/libhelloworld.la



回答3:


This is a good demonstration case for not using recursive make, because that simplifies the declaration of the executable depending on the library. Also, using a single Makefile.am helps with parallel builds (make -j3).

I have completed the example and put it up at github.com/ndim/cxx-automake-lib-and-main for your convenience.

The configure.ac now uses LT_INIT directly without deprecated macros, only generates one Makefile, and generates a helloworld-config.h config header to keep the compiler command line clean from all those -D defines:

AC_INIT([helloworld], [0.1], [bug-me-not], [helloworld], [this-url])
AC_CONFIG_SRCDIR([lib/helloworld.cpp])
AC_CONFIG_HEADERS([helloworld-config.h])
AC_CONFIG_MACRO_DIR([auto-m4])
AC_CONFIG_AUX_DIR([auto-aux])
AM_INIT_AUTOMAKE([
-Wall
-Werror
foreign
subdir-objects
])

AC_PROG_CXX
AM_PROG_AR
LT_INIT([disable-static])

AC_LANG([C++])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

The top-level Makefile.am is now the only Makefile.am:

ACLOCAL_AMFLAGS = -I auto-m4

EXTRA_DIST =
bin_PROGRAMS =
lib_LTLIBRARIES =

include include/Makefile-files
include lib/Makefile-files
include src/Makefile-files

Then include/Makefile-files deals with the header file which I put into include/helloworld/helloworld to help with keeping the include file namespace clean, and to prevent make from getting confused about the executable helloworld and the header file helloworld.

# -*- makefile-automake -*-
EXTRA_DIST += %reldir%/helloworld/helloworld
/* -*- c++ -*- */
#ifndef HELLOWORLD_HEADER
#define HELLOWORLD_HEADER

class helloworld {
public:
  void getvalue();
};

#endif /* !defined(HELLOWORLD_HEADER) */

Now, lib/Makefile-files will build libhelloworld.la from library source file lib/helloworld.cpp which I had to adapt a bit for the changed header name:

# -*- makefile-automake -*-

lib_LTLIBRARIES           += libhelloworld.la
libhelloworld_la_CPPFLAGS  = -I$(top_srcdir)/include
libhelloworld_la_SOURCES   = %reldir%/helloworld.cpp
#include "helloworld/helloworld"

void helloworld::getvalue() {
}

The helloworld program is defined in src/Makefile-files such that the dependency libhelloworld.la will be automatically (re)built if necessary. The source file src/main.cpp has been adapted for the new header name/location.

# -*- makefile-automake -*-

bin_PROGRAMS            += helloworld
helloworld_CPPFLAGS      = -I$(top_srcdir)/include
helloworld_SOURCES       = %reldir%/main.cpp
helloworld_LDADD         = libhelloworld.la
#include "helloworld/helloworld"

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


来源:https://stackoverflow.com/questions/60205338/how-a-c-program-cpp-work-with-header-h-and-libtool-la

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!