Table of Contents
One of the most important features of abuild is that a given build item automatically inherits the interfaces of not only all of its direct dependencies but of its indirect dependencies as well. There may be instances, however, in which this is undesirable. We present such a case here.
This example shows how we can create a C/C++ build item that
implements an “opaque wrapper” around some other
interface. In the
doc/example/opaque-wrapper
directory, there
are three directories: hidden
,
public
, and client
.
The hidden
item implements some interface.
The public
item implements a wrapper around
hidden
's interface, but uses
hidden
privately: only its source files, not
its header files, access files from hidden
:
opaque-wrapper/public/Public.hh
#ifndef __PUBLIC_HH__ #define __PUBLIC_HH__ class Public { public: void performOperation(); }; #endif // __PUBLIC_HH__
opaque-wrapper/public/Public.cc
#include "Public.hh" #include <Hidden.hh> void Public::performOperation() { Hidden h; h.doSomething(); h.doSomethingElse(); }
The intention is that users of public
should
not be able to access any parts of hidden
at
all. The client
directory contains an
example of a build item that uses public
.
It doesn't include any files from hidden
,
and if it were to try, it would get an error since the
hidden
directory is not in its include path.
However, it still must link against the
hidden
library. The
public
build item achieves this by resetting
the INCLUDES
interface variable in an
after-build file:
opaque-wrapper/public/Abuild.interface
INCLUDES = . LIBDIRS = $(ABUILD_OUTPUT_DIR) LIBS = opaque-public after-build hide-hidden.interface
opaque-wrapper/public/hide-hidden.interface
# Prevent those that depend upon us from seeing the INCLUDES that we saw reset INCLUDES # Re-insert our own include directory into the public interface INCLUDES = .
This way, items that depend on public
will
see only this item's includes and not those of the items it
depends on. Here is the output of abuild
ccxx_debug when run from the
client
directory:
opaque-wrapper-ccxx_debug.out
abuild: build starting abuild: opaque-client (abuild-<native>): ccxx_debug make: Entering directory `--topdir--/opaque-wrapper/client/abuild-<native>' INCLUDES = ../../public LIBDIRS = ../../public/abuild-<native> ../../hidden/abuild-<native> LIBS = opaque-public opaque-hidden make: Leaving directory `--topdir--/opaque-wrapper/client/abuild-<native>' abuild: build complete
As you can see, there is no reference to the
hidden/include
directory even though its
library and library directory are present in
opaque-client
's compilation environment.