$darkmode
Elektra 0.11.0
Library Directory Structure

Problem

Currently src/libs/elektra contains the source of several libraries. Each of the libraries should have its own folder. Furthermore, we need to allow rust source to exist in parallel.

Constraints

Assumptions

Considered Alternatives

Decision

We use this directory tree (YAML syntax for highlighting):

1 doc:
2 benchmarks:
3 examples:
4 scripts:
5 src:
6  include:
7  # headers that don't belong to a specific library
8  libs:
9  core-c: C implementation of libelektra-core.so
10  core-rust: Rust implementation of libelektra-core.so
11  opts: libelektra-opts.so has only a single implementation, so no suffix
12  # plugins and tools use the same suffix idea as above
13  plugins:
14  tools:
15  bindings:
16  rust: Rust bindings
17  cpp: C++ bindings
18  java: Java bindings
19  tests:
20  shell: shell script tests
21  cframework: framework for C tests
22  gtest-framework: framework for C++ tests
23  abi: ABI compatibility tests
24  # build tool configuration files to create a single root project for every language
25  # this is improves IDE support
26  CMakeLists.txt
27  build.gradle
28  Cargo.toml

Unit tests (*) (e.g. the old tests/ctest, tests/kdb) should be bundled with the code they are testing: e.g. in Rust test code is in the same file, in C/C++ it should be in the same folder and in Java a separate source set in the same module is used. This makes it easier to find the tests for a library, and also creates a uniform structure (in Rust or Java it would be harder to put tests into the current structure). System tests that test multiple components live in the src/tests folder.

(*) The term "unit test" is used very loosely here. Most tests for e.g. the kdb tool will not, strictly speaking, be unit tests, since they don't replace dependencies with mocks/fakes and instead test the whole kdb tool.

For now benchmarks will remain in the top-level benchmarks directory, unless there is a language specific reason to have them next to the code they benchmark (like unit-tests). In future this may change to facilitate automated performance-regression tests.

Rationale

This setup, allows to find a plugin/library/etc. just by knowing its code type (library/plugin/etc.) and its name. At the same time, using language suffixes allows having multiple implementations in different languages. Finally, whenever possible there should be project config file in the top-level src directory for every language. This will improve IDE support and make it possible to treat all code from one language as a single project. However, it is important that modularity is not lost in the process. It must still be possible to depend on individual libraries in CMake, without having to build everything else that is written in the same language.

Therefore, the top-level project should only exist, if the language allows projects that only include sub-modules. Otherwise, fully separate projects for every plugin/library/etc. should be used to preserve modularity.

Implications

Related Decisions

Notes