Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expected project/directory structure for Automake?

I'm developing a static C library, and had been using a bare-bones Makefile. We're now having to support offsite installs and whatnot, and the time has come to move to a more robust build standard. I really want that to be autotools -- I love the automatic conformance to the GNU Build System and I also have found it pretty easy to work with.

That said, I have a problem.

Here's a rough outline of how the project has been structured:

project/
    common/
       pkg/
    inc/
    src/
       submodule1/
           some_thing/
           some_other_thing/
       submodule2/
        . . .

common contains header files that would be installed on a target system -- one header directly under common, and some other stuff in common/pkg. (Well, it's not really pkg, that's just an example.) Everything under common is .h.

inc contains internal include files that are strictly implementation-relevant and shouldn't be exposed. Everything under inc is .h.

src has a directory for each of a number of submodules, and each of the submodules may or may not be divided into pieces (subsubmodules, if you want). Everything under src is .c.

The original makefile would set a SOURCES variable consisting of every .c file found recursively in src, add -I./common -I./inc, build the object files, and archive them into a library. Pretty straightforward.

Well, with automake, it doesn't seem so simple. I figured out about adding flags to a build target, for instance `project_CPPFLAGS=-I./inc -I./common" -- this solves part of the problem, but I feel like I'm doing something wrong, somehow.

With those (suboptimal?) settings, I can get automake building and linking the library, which is exciting enough already, but the real reason I'm here is make install.

The main problem is this:

common contains the public interface to the library, if you will. It is needed to build the sources, but it also needs to be installed. If I include it from project/, then automake will see paths like common/thing.h and common/pkg/other.h, and get the paths wrong in includedir on installation. I thought about having it recurse into that directory to build a project that only has installation headers, but that not only smells bad, it didn't work when I tried it. The library headers need a specific tree structure -- how do I maintain the lib header tree structure, make them available to all the source files, and install them rooted from common?

Additionally, is there some more elegant way to handle includes than by forcing -I? I know I have to specify them as HEADERS to get them in distribution packages, but that doesn't actually seem to make them available to be included, leaving me a bit lost.

I feel like automake (and perhaps GNU in general) is expecting some structure to my project that I'm just not seeing. If that's the case, please tell me -- I'm perfectly willing to spend some time refactoring/reorganizing the project. I really do feel like I'm missing some philosophical bit -- the current structure was designed without guidance or experience, and I am in no way attached to it.

Any help is appreciated.

like image 310
shanef22 Avatar asked Feb 25 '12 03:02

shanef22


1 Answers

I do not see anything wrong with using -I. It even allows to consistently use the very #include <pkg/foo.h> notation in both your tree, and third-party projects making use of pkg/foo.h.

AM_CPPFLAGS = -I${top_srcdir}/common -I${top_srcdir}/inc

To install the files in common, you can either utilize SUBDIRS = common (from toplevel Makefile.am),

# <top>/common/Makefile.am
nobase_include_HEADERS = pkg/foo.h pkg2/bar.h

or, if you choose to do a non-recursive approach, something like

# <top>/Makefile.am
xxxpkgdir = ${includedir}/pkg
xxxpkg_HEADERS = common/pkg/foo.h
xxxpkg2dir = ${includedir}/pkg2
xxxpkg2_HEADERS = common/pkg2/bar.h
like image 120
jørgensen Avatar answered Nov 11 '22 20:11

jørgensen