Skip to content
forked from frutiger/bdemeta

Build and test BDE-style code

Notifications You must be signed in to change notification settings

cppguru/bdemeta

 
 

Repository files navigation

CI Coverage

bdemeta

Build and test BDE-style code.

Synopsis

bdemeta walk [-t] CONFIG TARGET [TARGET ...]
bdemeta dot [-t] CONFIG TARGET [TARGET ...]
bdemeta cmake [-t] CONFIG TARGET [TARGET ...]
bdemeta runtests [TEST ...]

Description

bdemeta is a set of basic tools to assist building and testing BDE-style source trees. It can generate CMake files for package groups and test drivers within them. It can also invoke BDE-style test drivers.

bdemeta supports finding targets across disconnected directory structures.

Installation

Platforms running Python 3.7 or newer are supported. Install using pip:

$ pip install git+https://github.com/frutiger/bdemeta

Modes

bdemeta runs in one of four modes as given by the first positional argument:

  • walk [-t] CONFIG TARGET [TARGET ...]:
    Walk and topologically sort dependencies

  • dot [-t] CONFIG TARGET [TARGET ...]:
    Generate a directed graph in the DOT language

  • cmake [-t] CONFIG TARGET [TARGET ...]:
    Generate a CMake lists file

  • runtests [-e EXECUTOR] [TEST ...]:
    Run specified or discovered unit tests

Configuration

bdemeta is configured by a JSON configuration file supplied as the first argument to the walk, dot and cmake modes. The configuration is as follows:

{
    "roots": [
        "<root>",
        ...
    ],
    "standalones": [
        "<standalone>",
        ...
    ],
    "providers": {
        "<target1>: ["<target2>", "<target3>", ...],
        ...
    },
    "runtime_libraries": ["<target4>", "<target5">, ...],
    "pkg_configs": {
        "<target6>": "<pkg1>",
        ...
    },
    "extra_dependencies": {
        "<target7>": ["<target8>", "<target9>", ...],
        ...
    },
    "plugin_tests": ["<target10>", "<target11>", ...]
}

The meaning of each block is explained below.

Roots

bdemeta will look for targets in directories specified by (possibly multiple) <root>s in the configuration. This makes it easy to build code across multiple BDE-style repositories, including your own. Relative <root>s are considered relative to the path of the configuration file, not relative to the current working directory.

In particular, bdemeta will search for targets by name within each <root> directory:

  • package groups in <root>/groups/<name>
  • standalone packages in <root>/standalones/<name>
  • applications in <root>/applications/<name> (these must contain at least one main file named <name>.m.cpp, but may contain additional components if listed in <root>/applications/<name>/package/<name>.mem)
  • third party CMake packages in:
    • <root>/thirdparty/CMakeLists.txt
    • <root>/CMakeLists.txt

The set of directories searched for standalone packages can be extended by specifying multiple <standalone> directories in the configuration.

Test-only dependencies

Supplying -t (or --test-deps) to the walk, dot or cmake modes will include <target>.t.dep when calculating dependencies of a BDE-style package group or package.

Target providers

A number of third party targets may be specified by a single CMakeLists.txt. However, the dependency from a target is on another target (i.e. library), not on a directory. A "target provider" may be used to specify that a directory containing a CMakeLists.txt will actually provide other targets.

The sample configuration above indicates that the CMakeLists.txt in <target1> will actually provide <target2> and <target3>. This allows bdemeta to consider the targets <target2> and <target3> found once it finds <target1>.

Note that the providers block is optional.

Runtime libraries

Some platforms require undefined symbols to be provided at link time. However, when building plug-in libraries, some symbols are expected to be supplied by the hosting executable at runtime. Enumerating the libraries that contain symbols that will be supplied at runtime allows bdemeta to ensure that any targets that depend those libraries are linked allowing undefined symbols.

The sample configuration indicates that any target depending (transitively or not) on <target4> or <target5> should be linked allowing undefined symbols.

Note that the runtime_libraries block is optional.

Package Config

A target may have its dependencies defined by the pkg-config, already available on the system. The pkg_configs block is consulted to map a target name <target6> to a pkg-config package named <pkg1>. This block is only consulted if the search through every root as described above has been exhausted.

Note that the pkg_configs block is optional.

Extra Dependencies

Often a CMake target or a PkgConfig target may require additional dependencies that bdemeta is expected to resolve. Since bdemeta does not parse CMake files, it needs to be informed about such dependencies. The extra_dependencies block introduces a dependency from <target7> onto <target8>, <target9>, etc.

Plugin Tests

Code that is intended to be loaded as a shared library or plugin into another program will often need symbols to provided by the hosting program. In order to facilitate testing of such libraries, these targets can be declared to require "plugin tests".

<target10>, <target11>, etc. will have test drivers generated as shared libraries instead of standalone executables (assuming they are BDE-style targets). Some separate hosting program will be required to load and execute these tests.

CMake

For every target specified to the cmake subcommand, bdemeta walks all transitive dependencies based on the configuration described above.

For each BDE-type group or package dependency, bdemeta generates:

  • a CMake library target
  • a CMake executable target for each test driver
  • a CMake custom target comprising all the test drivers, named <name>.t
  • a 'development' install target for the library & headers
  • a 'runtime' install target for the library

For each BDE-type application dependency, bdemeta generates a CMake executable target, comprising the <name>.m.cpp main file in addition to any components listed in <name>.mem.

For each PkgConfig-type dependency, bdemeta generates a CMake interface target consisting of the discovered include directories, compile options and link libraries.

Running Tests

The runtests subcommand is provided as a helper utility to iterate through multiple test drivers in parallel supporting BDE-style test case status codes. In particular, each driver takes the test case number to run as the first command-line argument and exits with 0 upon success, -1 if there is no such test case and greater than 0 upon failure.

By default, test drivers are executed by the system. If a custom executor is specified with the -e flag, that is invoked instead, supplying the test driver and test case as trailing arguments. The status codes from the custom executor must match the rules described in the previous paragraph.

License

Copyright (C) 2013 Masud Rahman

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

Build and test BDE-style code

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 100.0%