1
votes

I have the following files

├── configure.ac
├── main.cpp
├── Makefile.am
└── procs
    ├── Makefile.am
    ├── proc1
    │   └── subprocs
    │       ├── subprocA
    │       │   ├── ProcA_SubprocA.cc
    │       │   └── ProcA_SubprocA.h
    │       └── subprocB
    │           ├── ProcA_SubprocB.cc
    │           └── ProcA_SubprocB.h
    ├── proc2
    │   └── subprocs
    │       ├── subprocA
    │       │   ├── ProcB_SubprocA.cc
    │       │   └── ProcB_SubprocA.h
    │       └── subprocB
    │           ├── ProcB_SubprocB.cc
    │           └── ProcB_SubprocB.h
    └── Subprocs.h

My goal is to create a library from everything in procs so it can be used in main.cpp which could look something like this:

main.cpp

#include "Subprocs.h"

int main(){

    ProcA_SubprocA * p = new ProcA_SubprocA();
    p->use();
    delete p;

    return 0;
}

I would like to have all the includes of the subprocs in Subprocs.h, so it can be used as some kind of interface:

Subprocs.h

#include "ProcA_SubprocA.h"
#include "ProcA_SubprocB.h"
#include "ProcB_SubprocA.h"
#include "ProcB_SubprocB.h"

My configure.ac looks like this:

configure.ac

AC_PREREQ([2.69])
AC_INIT([main], [0.1])
AM_INIT_AUTOMAKE([foreign subdir-objects])

#AC_CONFIG_MACRO_DIR([m4]) 
#LT_INIT

AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB

AC_CONFIG_FILES([Makefile procs/Makefile])
AC_OUTPUT

and my Makefile.am's like this

Makefile.am

SUBDIRS = procs

AM_CPPFLAGS = -Iprocs

bin_PROGRAMS = main
main_SOURCES = main.cpp
#added:
main_LDADD = procs/libprocs.a

#ACLOCAL_AMFLAGS = -I m4

procs/Makefile.am

AM_CPPFLAGS = -Iproc1/subprocs/subprocA -Iproc1/subprocs/subprocB \
              -Iproc2/subprocs/subprocA -Iproc2/subprocs/subprocB

#lib_LIBRARIES = libprocs.la
noinst_LIBRARIES = libprocs.a
libprocs_a_SOURCES = Subprocs.h \
                      proc1/subprocs/subprocA/ProcA_SubprocA.cc proc1/subprocs/subprocA/ProcA_SubprocA.h \
                      proc1/subprocs/subprocB/ProcA_SubprocB.cc proc1/subprocs/subprocB/ProcA_SubprocB.h \
                      proc2/subprocs/subprocA/ProcB_SubprocA.cc proc2/subprocs/subprocA/ProcB_SubprocA.h \
                      proc2/subprocs/subprocB/ProcB_SubprocB.cc proc2/subprocs/subprocB/ProcB_SubprocB.h

When I type

#libtoolize && autoreconf -i -f && ./configure && make
autoreconf -i -f && ./configure && make

I get a file called libprocs.la in procs but I don't get a binary. I am also fairly certain that my Makefiles are wrong since I can't even compile main.cpp by hand.

Is it at all possible to do what I want here? Or am I overthinking this and I don't even need a library in the first place? The important part for me is that main.cpp only includes Subprocs.h which then contains all includes of the subprocs.

Thank you in advance!

1
libtoolize modifies your Makefile.am and configure.ac files, which is why you must autoreconf afterwards. If that's the way you intend to go (and it's by no means wrong) then the libtoolize and autoreconf should be done once, not as part of every build. Moreover, in that case it would be the post-libtoolize files that would be relevant to this question (it looks like that may indeed be what you presented, but please clarify). - John Bollinger
Is the library intended only for the program you are building, or is it your intention to provide it for other programs, too? Is it important for it to be a shared library? Inasmuch as you do not appear to be installing the library's headers, I'm supposing that the library is for the one program only, and therefore that it does not need to be a shared library or even installed as a standalone library in its own right. Please confirm. - John Bollinger
The library is only intended for this program. I am trying to setup a structure here that would enable me to add new procs (proc3, proc4, ...) later with minimal effort and if possible no changes to anything above the procs directory. - Lxndr
I think you're going to a lot of work for negligible benefit. The structure you're setting up seems to be harder to maintain overall, and I don't see how it has any advantage over a flat structure for adding new procs. - John Bollinger

1 Answers

1
votes

There are numerous oddities in what you've presented, and one clear error. You say,

I get a file called libprocs.la in procs but I don't get a binary. I am also fairly certain that my Makefiles are wrong since I can't even compile main.cpp by hand.

Surely make's output contains one or more error messages that explain why the build fails. Unless your makeing only the procs subdirectory in the first place, I guess, in which case of course you would not be getting main built.

But I'm reasonably confident that I can guess: you're getting a linker error complaining that it can't find ProcA_SubprocA::ProcA_SubprocA. This would be because although your Makefile specifies that the library should be built (and also installed), it nowhere says that it needs to be linked into main. There's a pretty easy fix for that, which I will return to in a moment.

First, however, let's talk about libprocs.la. The .la suffix is meaningful to the Autotools, designating a "libtool archive", but you're actually building it as an ordinary static library. Indeed libtool isn't doing anything particularly useful for you here; I would dump it by removing the LT_INIT from your configure.ac (and do not run libtoolize again, as it will put that back). Then, change the name of the library to be built to the more standard libprocs.a.

Furthermore, since this library seems to be intended only for use with the one program being built, it is unhelpful to include it in the install in its own right. Therefore, instead of designating it in lib_LIBRARIES, designate it as a non-installed convenience library:

noinst_LIBRARIES = libprocs.a

You will then need to make a corresponding change to the library's SOURCES variable:

libprocs_la_SOURCES = ...

libprocs_a_SOURCES = ...

Coming back to the main program now, you need to tell make (and Automake) that the library needs to be linked into program main. There are a few variations on how you could do that, but I'm going to suggest a fairly simple one:

main_LDADD = procs/libprocs.a

After those changes, rerun autoreconf (but not libtoolize). Remember, however, that you need to run that only after changing Autotools sources -- just Makefile.am and configure.ac files in your case. It is a detail of maintaining and developing the package and its build system in particular. It should not be a routine part of building or installing the package.