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.