Boost logo

Boost-Build :

Subject: Re: [Boost-build] Compiling header files independently as a test.
From: Tom Brown (tabsoftwareconsulting_at_[hidden])
Date: 2018-03-18 18:27:57

Hi Steven,

On 3/17/18 7:58 PM, Steven Watanabe via Boost-build wrote:
> On 03/16/2018 02:13 PM, Thomas Brown via Boost-build wrote:
>> 1. I implement the tests in the library's Jamfile since that is where
>> the actual header file names are known. I actually put all required
>> files (headers, sources, etc.) in the sources list of the alias or
>> lib. Is that something others are doing? This forces me to put the
>> source file names and header file names into separate variables so I
>> can iterate over them. I also do this in order to specify the sources
>> for a doxygen target within Boost.Build.
> I've never seen that before. Listing the headers
> as sources for a library will just cause them to
> be ignored.

That is true. However, a missing header file in a lib target will
trigger an error from Boost.Build, which I find useful to let me know
when I miss something.

I use it like this in order to get an error if a public header does not
exist. The install target is usually not run during development, so the
error source happen later in the development process if that were the
only place it were checked.

# untested
import package ;

local x_headers = x.hpp ;
local x_sources = x.cpp ;
lib x : $(x_headers) $(x_sources) ;

explicit install ;
package.install install
   : # requirements
   : # binaries
   : # libraries
   : # headers

>> 2. I'd really prefer to iterate through the sources of any target (at
>> least any alias or lib) to run the compile-header tests in the test
>> Jamfile without knowing what they are named. This would actually make
>> it possible to have a separate Jamfile to generate doxygen as well.

> Iterating over the sources of a target is a bad idea. > Instead, use an alias and handle the processing at the
> virtual target layer (via generate, a generator, or
> a custom target class). In particular, for checking
> headers, you can use a composing generator to handle
> all of the following:
> - compile each header in a separate translation unit.
> - include all headers in a single translation unit (useful
> for catching duplicate #include guards)
> - link two translation units that #include all headers. (catches
> functions that should be inlined)

Thanks, I will give this a try. I'm not sure I fully understand how I
would do this yet, but I'll see if I can figure it out. I've written a
lot of Boost.Build, but still am not comfortable just whipping up a
custom target class. Maybe this will be the project where I finally
understand it :)

I think I can satisfy my requirement of having the library definition
and tests defined separately by making the compile-headers target be
explicit in the library's Jamfile and request it from the test Jamfile.

>> 3. The "compile-header" target might require more information if the
>> library has dependencies, which have to be specified in both the
>> library and the compile-header targets. This seems to usually be
>> handled by depending on the library itself in the compile-header
>> target, so maybe it's not a big deal, but it is a bit strange to say
>> that compiling the header that is part of libx depends on libx.
> <use>libx will pick up the usage-requirements, but otherwise
> ignore libx, which I think is the behavior you want.

I'll give that a try as well. I vaguely having subtle issues with <use>
in the past, but I think they were fixed several years ago.

>> I've included inline some code that reflects what I am currently
>> doing. It is extremely preliminary. I could see, at the minimum,
>> adding a "compile-header" and maybe "compile-header-fail" (not
>> implemented here)
> I don't think that compile-header-fail is useful.

I agree. I wish I hadn't mentioned it :)

I'll post my attempt at an actual target to do this in the next few days
for critique.


Boost-Build list run by bdawes at, david.abrahams at, gregod at, cpdaniel at, john at