Monthly Archives: April 2022

Building multiple inter-dependent autotools based projects

One of the main reasons for this blog is documenting things for my future self. This post is one of these.

Building a HTTP REST API with C++ is a quite unique type of challenge, but doing it with libhttpserver takes a lot of the lower level protocol (read: HTTP and below) burden away from you, and lets you focus on the content part of your problem. This is what we did for a new project at work lately. But sometimes when working with external dependencies you hit some bugs and corner cases and have to dig into those projects.

Building libhttpserver is almost straight forward, if you had already built autotools based projects before. You’ll notice however it depends on a quite recent version of libmicrohttpd. So the task for hacking on libhttpserver is to build both libraries from source, without interfering with the rest of your system.

The usual way to build autotools based projects is like this:

% ./configure
% make

(It works exactly like this if building from an extracted source tarball. There’s another step in front of those, if you build from a Git working copy.)

Now after the naïve way to build libmicrohttpd, how can we tell libhttpserver to pick that up as a dependency? What I do is “installing” them both to the same place in a tree just for this purpose, and I use the --prefix option of ./configure for that with a directory I created before. So for libmicrohttpd from Git it would look like this:

% ./bootstrap
% mkdir -p build && cd build
% ../configure --prefix=/home/adahl/build/sysroot/http
% make
% make install

After that I have the following file tree:

% tree ~/build/sysroot/http
/home/adahl/build/sysroot/http
├── include
│   └── microhttpd.h
├── lib
│   ├── libmicrohttpd.a
│   ├── libmicrohttpd.la
│   ├── libmicrohttpd.so -> libmicrohttpd.so.12.60.0
│   ├── libmicrohttpd.so.12 -> libmicrohttpd.so.12.60.0
│   ├── libmicrohttpd.so.12.60.0
│   └── pkgconfig
│       └── libmicrohttpd.pc
└── share
    ├── info
    │   ├── dir
    │   ├── libmicrohttpd.info
    │   ├── libmicrohttpd_performance_data.png
    │   └── libmicrohttpd-tutorial.info
    └── man
        └── man3
            └── libmicrohttpd.3

7 directories, 12 files

So let’s try to build libhttpserver from Git master now:

% ./bootstrap
% mkdir -p build && cd build
% ../configure --prefix=/home/adahl/build/sysroot/http

But that gives:

checking for microhttpd.h... no
configure: error: "microhttpd.h not found"

So just giving the prefix is not enough. We need to pass some directories to preprocessor (for finding header files) and linker (to link against the other shared lib). You can do it like this:

% CPPFLAGS=-I/home/adahl/build/sysroot/http/include LDFLAGS=-L/home/adahl/build/sysroot/http/lib ../configure --prefix=/home/adahl/build/sysroot/http

Looking complicated? I bet. In our case we have only two projects, but what if there are even more? Gnu autotools has a nice feature which can help here though: Overriding Default Configuration Setting with config.site. In short: Put those preprocessor, compiler, and linker flags into a special file in your install tree, and ./configure will pick it up automatically and use the settings. In my case, I create a file /home/adahl/build/sysroot/http/share/config.site and put in the following:

test -z "$LDFLAGS" && LDFLAGS=-L/home/adahl/build/sysroot/http/lib
test -z "$CPPFLAGS" && CPPFLAGS=-I/home/adahl/build/sysroot/http/include

We can omit that stuff when calling ./configure now and everything is found and compiled and linked together. We can tell it’s picked up by the very first line of ./configure output:

% ../configure --prefix=/home/adahl/build/sysroot/http  
configure: loading site script /home/adahl/build/sysroot/http/share/config.site
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
…

So that’s all for today, I hope it will help my future self to look up what that magic file is called, where it must be placed, and where the documentation for that can be found.

Update: I make use of this mechanism in some of my CMake superbuild projects, e.g. in glowing-tribble-build.