[build2] Build2 configuration for component based projects

asatsuyu at tutanota.com asatsuyu at tutanota.com
Mon Nov 13 08:29:13 UTC 2017

Hi Boris,

Thanks a lot for looking into this.

1) Canonical structure:

> While it will work, this structure is not "canonical". Practically, this
> means that it won't "fit" with other nice features and usage scenarios
> that expect the canonical/"parallel" structure like this:
> bld/cfg_A/
> bld/cfg_B/
> project/src/
> For example, in your setup you won't be able to package project/ as a
> bpkg package.

Changing the directory structure to match the canonical one should hopefully not be an issue. My main concern is to keep the config files for out-of-tree builds at hand to have them under version control. In particular, launching a build for a particular config should remain a straight forward operation (one simple command line ideally) after checking out the project from a git repo.

2) Second level of extension in file names:


> Also, using .t as a second level extension is asking for trouble (at
> least in build2). Again, you can make it work, it's just you will have
> to specify full extensions everywhere explicitly. So I would suggest
> that you use something else, e.g., efg_ZZZ-t.cpp.

I can understand that having a second level of extension is likely to raise issue. It is good to know that it can still work out this way though. In my case, switching to the name pattern you suggested is not an issue because I do not use hyphen characters in my current naming scheme. 


3) Link time issues:

>>  The code under the src directory is organized in "components" and each
>>  "component" is made up of three files (this is rather common I guess):
>>  - One .hpp file which contains function/struct/class declarations and
>>    inline/template functions implementations.
>>  - One .cpp file which contains the implementation of the non inline/
>>    template functions declared in the associated .hpp file.
>>  - One .t.cpp file which contains the test driver with a function for
>>    the function/struct/class declared in the associated .hpp file. [...]
>>  The description is probably oversimplified but that would already be
>>  nice to get the following tasks to work without having to modify the
>>  buildfile for each newly added component.
>>  - build the new/outdated object files (XXX.o and XXX.t.o)
>>  - build the new/outdated/failed test driver binary (XXX.t), run them
>>    and report failures if any. 
> Yes, you can do that. If you get the latest staged version of build2[1],
> then the following buildfile should do the trick (note that it assumes
> we are using the -t test naming instead of .t):

 When using the version of build2 that you indicated, things are working fine as long as the content of a given implementation file (e.g. cde/cde_XXX.cpp) remains unused outside of its test driver (e.g. cde/cde_XXX-t.cpp). In particular, it should work fine if the project is a header-only library.

To illustrate a situation where things do not seem to work, imagine that the test driver of the component efg_ZZZ (file efg/efg_ZZZ-t.cpp) calls a function "void foo()" declared in file "cde/cde_XXX.hpp" and implemented in file "cde/cde_XXX.cpp". In that case, a link time error that looks like the following is generated:

g++ -o bld/cfg_A/efg/efg_ZZZ bld/cfg_A/efg/efg_ZZZ.o bld/cfg_A/efg/efg_ZZZ-t.o
g++: error: undefined symbol: foo()

I am not sure to see a satisfying workaround at this point. In particular, the following ideas look either inefficient or impractical:

- Packaging all the object files into one big library. This would mean relinking every test driver of the project at build time after a change in any of the header or implementation file. The amount of superfluous work would be significant.
- Packaging all the object files within a given directory (e.g. "src/cde/") into a library (e.g. libcde). This would slightly reduce (but not suppress) the amount of superfluous work at build time at the expense of manually specifying and maintaining the dependencies between those libraries.

Do you see anything that could help solving this issue?

4) Minimizing the number of tests to run:

This item might worth a separate email thread, just let me know if you like me to start one. When issuing a command like "build2 '{test}(bld/cfg_A)'", every single test available seem to be run on every invocation. That's fine from the end user perspective who is expected to run the test suite at most once before the installation.

>From the developer perspective though it could be helpful to have a way to run only the test drivers that were either updated since the last "build2 test" command or unsuccessful during the last run. I realize that this is not ideal because a test does not only depend on the associated binary but also (at least) on the associated "testscript" file and the files eventually referenced in this "testscript" file.

That being said, it would be nice to find a simple solution that covers a common use case where the test depends only on its associated binary and its associated "testscript" file. Would this be an acceptable solution to identify such kind of tests in the the buildfile using a special option and to have them processed accordingly by build2? The default behavior would remain the current one if the option is not set for a given test.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.build2.org/archives/users/attachments/20171113/03595eb9/attachment.html>

More information about the users mailing list