BDE-Style Repository¶
Introduction¶
For a repository to be buildable with the BDE tools, it must have the following characteristics:
Must follow BDE Physical Code Organization.
Must provide BDE Metadata.
Terminology¶
- component¶
A component comprises a
.hand.cpppair, along with an associated test driver (.t.cppfile). E.g., the componentbslstl_mapcomprisesbslstl_map.handbslstl_map.cpp, and is associated with the test driver filebslstl_map.t.cpp.- package¶
A physical unit that comprises a collection of related components.
- package group¶
A physically cohesive unit that comprises a collection of packages.
- stand-alone package¶
A package that does not belong to a package group.
- UOR (Unit of Release)¶
A stand-alone package or a package group. Generally, UORs are the libraries (
.afiles or applications) that get deployed on a system. The names of UORs must be globally unique.
BDE Physical Code Organization¶
Units and Unique Names¶
Components, Packages, and Package Groups are all considered physical units inside of a repository. Unit names have the constraint that they must be globally unique. This characteristic of units greatly simplifies how we can reason about the source code.
Having globally unique component names allows BDE to use direct include
directives instead of relative ones, i.e., using #include <bdlt_date.h>
instead of #include "include/header.h". Using direct includes affords us
flexibility with development and deployment. Otherwise, we would not be able
to extract an arbitrary subset of our code for point distributions without
recreating our entire directory structure. Separately, our development process
for package groups may choose to locate headers differently when using code
withing the group compared with once the code is released.
The argument for angle brackets rather than quotes is similar: Angle brackets
<> provide full control over source of headers and can simulate the common
usage of double quotes "" simply by adding -I. to the compile line.
Having unique unit names is achieved in BDE via using a central name registry as well as following certain naming conventions:
The name of each package group is a unique mnemonic exactly three characters long (e.g.,
bsl).The name of a package should be prefixed with the name of the package group and should also be a mnemonic no longer than six characters (e.g.,
bslma).The name of a component should be prefixed by the name of the package in which the component is contained followed by an
_(e.g.,bslma_allocator).The name of a stand-alone package should be prefixed with
a_if it’s an adapter, andm_if it’s an application.All of the names should be in lower case.
For more details on naming conventions and design rules of components, packages, and package groups, please see BDE Physical Code Organization Guidelines.
Regular Components, Packages, and Package Groups¶
The source code must be organized into 3 hierarchical levels of aggregation (in order from smallest to largest): components, packages, and package groups. A package comprises a set of components; a package group comprises a set of packages.
By default, package groups should be located in <repo_root>/groups, and a
package belonging to a package group should be a sub-directory of that package
group.
For example, in BDE, the bsl package group contains the packages bsls
and bslma (in addition to many other packages). The bsls package
contains the components bsls_util and bsls_ident; The bslma package
contains the components bslma_allocator and bslma_testallocator. These
physical units should have the following structure on the file system:
<repo_root> `-- groups |-- bsl | |-- group | | |-- bsl.mem | | |-- bsl.dep | |-- bsls | | |-- package | | | |-- bsls.mem | | | |-- bsls.dep | | |-- bsls_ident.h | | |-- bsls_ident.cpp | | |-- bsls_ident.t.cpp | | |-- bsls_util.h | | |-- bsls_util.cpp | | |-- bsls_util.t.cpp | `-- bslma | |-- package | | |-- bslma.mem | | |-- bslma.dep | |-- bslma_allocator.h | |-- bslma_allocator.cpp | |-- bslma_allocator.t.cpp | |-- bslma_testallocator.h | |-- bslma_testallocator.cpp | `-- bslma_testallocator.t.cpp `-- bdl | `-- ...
Stand-Alone and Application Packages¶
Stand-alone packages are packages that do not belong to a package group.
An application package is a special kind of stand-alone package, with the main
difference being that an application package contains a <package>.m.cpp
file in which the main function is defined.
By default, application packages should be located in the applications
directory, adapter packages should be located in the adapters directory,
and other types of stand-alone packages can be located in the standalones
directory.
Non-standard Package Types¶
BDE repository can include source files that don’t conform to a standard BDE-style package. Often, the reason is to bundle an existing third-party package inside of a repository.
There are two common types of non-conforming packages: header-only packages and third-party packages.
Header-only Packages¶
Header-only packages are packages that contain header-only library or just a
set of headers. These packages do not behave like regular BDE packages in
that they do not contain BDE components. Nonetheless, mem file in those
packages still can be used to provide the list of headers contained in the
package.
Third-Party Packages¶
Third-party packages are not BDE-style packages and do not contain any
BDE Metadata. By default, these packages are located under
the thirdparty directory, and must be provided with a custom
CMakeLists.txt.
Note
Third-party packages mainly exist to simplify the build process for certain low-level libraries. A third-party package can be easily moved to its own repository if so desired, in which case the third-party package must be first separately built and installed before the original repository that depended on that third-party package can be built.
BDE Metadata¶
There are 3 types of metadata that can be applied to either a package or a package group in a BDE-style repository. Two types of metadata are required:
memDefine the members of a package or package group.
depDefine the dependencies of a package or package group.
And additional type of metadata is optional:
t.depDefine the dependencies of the test drivers for a package or package group.
Each type of metadata should be stored as a file in either the package
sub-directory in a package or the group sub-directory in a package group.
A metadata file’s name should begin with the package or package group to which
it applies, followed by a ., and finally followed by the type of the
metadata. For example, in the BDE libraries, the mem file of the package
group bsl is named bsl.mem and located at the path
<repo_root>/groups/bsl/group/bsl.mem; the dep file of the package
bslstl is named bslstl.dep and located at the path
<repo_root>/groups/bsl/group/bslstl.dep.
Mem File¶
A package mem file defines the list of member components in the package. A
package group mem file defines the list of member packages in the package
group.
Each line of a mem file contains a single entry (a component or a package).
Blank lines are ignored and a # within a line marks the remainder as a
comment.
For example:
Dep File¶
A dep file describes the allowed dependencies for either a package
or a package-group. A package-group’s dep file describes the other
package-groups that components within that package-group may depend on.
Similarly, a package’s dep file describes the other packages within
the same package-group that components within that package may
depend on. Note that a package’s dep file should not refer to other
package-groups, since the dependencies on other package-groups are
inherited from the package-group-level dep file.
Each line of a dep file contains a single entry (a package or a package
group). Blank lines are ignored and a # within a line marks the remainder
as a comment.
For example: