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
.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With