1

I have a bit of a challenge for the meson experts out there.

My newest C++ project (a library) is structured according to The Pitchfork Layout. As is allowed by that convention, I have decided to use merged header and merged test placement. This basically means that my header files, source files, and test source files are all part of the same src directory structure.

Furthermore, my code is organized into multiple subdirectories based on the purpose it fulfills (e.g. utilities, algorithms, containers, ...).

In essence, what I have is (this is only an example):

<project>
├── meson.build
└── src/<project>
    ├── algorithms
    │   ├── meson.build
    │   ├── sort.hpp
    │   ├── sort.cpp
    │   ├── sort.test.cpp
    │   ├── transform.hpp
    │   ├── transform.cpp
    │   └── transform.test.cpp
    ├── containers
    │   ├── meson.build
    │   └── ...
    └── utilities
        ├── meson.build
        └── ...

The challenge now comes in writing the meson build files to build both the library and the unit tests. The unit tests obviously depend on the library being build and I would not have the library object ready until all build files have been processed at least once. So there is no way for me to also define the test executables in the meson build files because I need them to link with the library.

Solutions I have come up with so far:

  • Define a lib_sources and test_sources lists in the root build file and let all subdirectories add source files to those lists to then in the root build file define the library and test executable.
  • Let each subdirectory create its own library and test executable. Then visit the subdirectories in the correct order to preserve dependencies (e.g. visit utilities first, then algorithms, then containers). The subdirectories that are visited later can then link with the libraries of earlier subdirectories. And in the root build file create a single library that combines all sublibraries.

I am currently in favor of the second approach because each subdirectory defines its own targets so the build configuration is not centralized. The disadvantage is higher complexity, I guess.

How would I ideally configure the meson build files for a project layout like this?

(Note: yes, I could change the layout and have separate test placement, but that defeats the purpose of this "challenge" where merged test placement is a must-have)

Eljay
  • 4,648
  • 3
  • 16
  • 27
Maarten Bamelis
  • 2,243
  • 19
  • 32

1 Answers1

1

The second option you describe is the usual way I do it. Tests are defined in the directories next to the libs they test, with things like utility libraries evaluated first. The other option would be to define the meson tests in src/<project>/meson.build after all of the individual libraries are defined.

In my opinion though, this is a good reason to use convenience libraries, (not installed intermediate static libraries). You can link your tests with those libraries, and link those libraries into a final library. This can be useful if the final library can be shared, and thus may not expose all the symbols available internally.

dcbaker
  • 643
  • 2
  • 7
  • This is the approach I have implemented in my project and I like it very much. Writing the meson build files for the subdirectories is a bit of boilerplate but it also keeps the build-related stuff close to the actual code, which is a big plus in my opinion. And indeed, I am linking the intermediate libraries (well, actually the intermediate object files) into a single library in the end. – Maarten Bamelis Dec 24 '21 at 14:55