Boost logo

Boost :

Subject: Re: [boost] CMake and Boost Build tests
From: Edward Diener (eldiener_at_[hidden])
Date: 2017-07-27 15:19:00

On 7/27/2017 10:45 AM, paul via Boost wrote:
> On Wed, 2017-07-26 at 22:48 -0400, Edward Diener via Boost wrote:
>> On 7/26/2017 3:42 PM, paul via Boost wrote:
>>> On Wed, 2017-07-26 at 14:49 -0400, Edward Diener via Boost wrote:
>>>> Following John Maddock's appeal for practical solutions related to the
>>>> move to CMake, I would like to know what the CMake equivalent is to the
>>>> Boost Build unit test functionality.
>>>> In other words what do I write for CMake in order to do a Boost Build
>>>> compile, compile-fail, link, link-fail, run, and run-fail unit tests ?
>>> For a run test, you would do, something like:
>>> add_executable(footest footest.cpp)
>>> add_test(NAME footest COMMAND $<TARGET_FILE:footest>)
>> OK, that makes sense.
>>> For a compile/link test:
>>> add_library(footest STATIC EXCLUDE_FROM_ALL footest.cpp)
>>> add_test(NAME footest COMMAND ${CMAKE_COMMAND} --build . --target footest
>>> --
>> Why am I adding a library when all I am trying to do is see whether
>> source file(s) can be compiled to their object files successfully ( the
>> compile test ) or whether source file(s) can be compiled to their object
>> files successfully then linked as an executable without linking errors (
>> the link test ) ?
> You have to add a target to be built, and then the test will invoke this
> target. Tests in cmake are just commands that can do anything, and in this
> case we instruct cmake to build a target. The reason its a library and not an
> executable is so that a `main` function is not needed.

But a 'compile' or 'link' rule always attempts at compiling or linking
an executable anyway, which has a 'main' function.

> Of course, this will test both compiling and linking together, as there is no
> separation for this in cmake.
>>> To make the tests with expected failures, just set a property:
>>> set_tests_properties(footest PROPERTIES WILL_FAIL TRUE)
>> OK, thanks !
>>> You also can check for certain output, which nice for checking that the
>>> compile fail tests has triggered the static assert.
>>> Ideally, the BCMTest module can make this simpler:
>>> Which you can write the equivalent tests like this:
>>> Run test:
>>> bcm_test(NAME footest SOURCES footest.cpp)
>>> Run fail test:
>>> bcm_test(NAME footest SOURCES footest.cpp WILL_FAIL)
>>> Compile test:
>>> bcm_test(NAME footest SOURCES footest.cpp COMPILE_ONLY)
>>> Compile fail test:
>>> bcm_test(NAME footest SOURCES footest.cpp COMPILE_ONLY WILL_FAIL)
>> Thanks !
>>>> Does CMake have an equivalent to the Boost Build alias rule ?
>>> You can create interface target that includes the set of targets.
>>> add_library(core INTERFACE)
>>> target_link_libraries(core INTERFACE im reader writer)
>> Thanks I will look at the use of INTERFACE.
>>>> or the
>>>> Boost Build project rule ?
>>> Hmm, I am not sure how this is relevant to cmake.
>> For the purposes of unit tests the project rule lets the developer set
>> usage requirements for all tests in the jamfile, rather than having to
>> repeat the usage requirements for each test. Since usage requirements in
>> Boost Build can be pretty specific depending on the compiler being used
>> the entire usage requirements for all tests can be pretty extensive.
>> Having to repeat that extensive list of usage requirements for every
>> test would be a PITA.
> Well you can use the global function such as `add_compile_options` or
> `link_libraries` but these are discouraged as this will apply to every target
> created in the directory(and the usage requirements are not propagated).

That is actually what I want and is the equivalent of the Boost Build
'project' rule in a test jamfile with the 'requirements' options. Why
this is discouraged I would not know. Surely if you run a large number
of tests in a Boost Build test jamfile, it is much easier to specify
requirements for all test in one place rather than repeat them for each
and every test. This is especially true when requirements are based on
particular compilers possibly with particular versions of those compilers.

> So in
> general using per-target is preferred.
> However, in BCM, I have `bcm_link_libraries` that will link in those libraries
> when calling `bcm_test`, and can be excluded with the `NO_TEST_LIBS` option.
> So this provides the same convenience as the project rule. Although, a lot of
> cmake projects just write their own custom function to add the tests.

Where is your BCM ? Is this going to be used by the CMake implementation
in Boost as mandated by the steering committee ? I am all in favor of
CMake code which makes the transition between Boost Build and CMake as
transparent as possible. If I, as a library developer, am expected to
provide CMake equivalents to my Boost Build unit tests and CMake
equivalents to my Boost Build doc generation I want as high a
boilerplate level as possible.

Boost list run by bdawes at, gregod at, cpdaniel at, john at