Building from source
Cowl can be built and run on Windows, macOS and Linux. We have successfully deployed it to a wider range of platforms, including tiny microcontrollers, with relatively minor build system setup. It can be compiled either as a static or dynamic library.
In order to compile the library, you will need at a minimum:
There are additional requirements depending on which additional components you would like to build or compile (e.g. readers).
Doxygen version 1.8 or later.
(optional) Sphinx version 2.0 or later, Breathe and the Read The Docs Theme.
Sphinx is optional as Doxygen will already generate some form of HTML docs, though not as fancy as the ones you are viewing.
Downloading the sources
You can find Cowl’s code on its git repository. Please note that it contains
submodules, so it is recommended that you clone it using the
git clone --recursive <repo URL> <dir>
The following commands allow you to build Cowl:
# Generate the build system cmake -B cmake-build # [Optional] Edit build settings (build type, optimization options, etc.) ccmake cmake-build # Build the libraries and copy public headers into the output dir cmake --build cmake-build # [Optional] Build the documentation cmake --build cmake-build --target cowl-docs
Programming with Cowl
The easiest way to get started is by checking out the provided examples. However, in order to understand the principles behind the API, reading this section is strongly recommended.
Before making any API call, you must invoke
cowl_init(), which is
needed in order to initialize the library’s internal state.
Calling API members without initializing the API is undefined behavior.
In order to query an ontology you must first deserialize it, which can be done via
CowlManager. Cowl can use multiple readers, either built-in or provided by the user.
For further information, refer to the related documentation.
OWL ontologies may import other ontologies, which may involve loading them from mass storage or retrieving them from the network. Cowl’s approach to imports reflects its focus on portability, so ontology retrieval is delegated to the end user.
The core type of the API is
CowlOntology, which consists of a set of
instances. The base mechanism for querying a
CowlOntology is invoking its iterator
member functions, which generally accept
CowlIterator is a wrapper around a function that is called for every element matched
by the query. By providing a generic context pointer, you can plug any custom data structure
(loggers, collections, etc.), which allows for arbitrarily complex queries.
Ontology editing and writing
Ontologies can be created from scratch, or existing ontologies can be edited by adding
or removing axioms, annotations and other constructs, as allowed by the
Edited ontologies can then be written in any supported syntax
(see the related documentation).
Under the hood
This section illustrates a few important low-level details that you need to know in order to correctly use the library.
Cowl uses reference counting for memory management.
Reference counts are increased and decreased via
release member functions
available for every data structure. The API docs are very explicit about which functions
return already retained instances, which you must release. If nothing is specified,
then the returned instance is not retained, meaning its lifetime is generally tied
to that of some other object. If you need to keep it alive after its owner
has been deallocated, you must retain it.
Since the OWL 2 specification is highly hierarchical, the API makes extensive use
of pseudo-inheritance for structs. Every data structure pseudo-inherits from
whose concrete type can be queried via
Pseudo-inheritance allows you, as an example, to cast a
CowlObject and back. Of course, if the API returns a base pseudo-class
CowlObject, and you are unsure about its concrete subclass,
you can check its type via
get_type functions (e.g.
and cast accordingly. The API docs for type enumerations explicitly state the concrete type
associated with every enumeration value.