Boost logo

Boost :

From: Gennadiy Rozental (gennadiy.rozental_at_[hidden])
Date: 2006-11-08 15:14:50


"Juergen Hunold" <hunold_at_[hidden]> wrote in message
news:200611082043.27180.hunold_at_ivembh.de...
> > No. DLL Support is implemented. Boost.Test Jamfile is updated also
> > to support this

> But not Jamfile.v2

Yes. That's right. I know nothing about Boost.Build V2 and never supported
second file.

> Please find test_build.Jamfile.v2 attached for enabling shared linking
> using msvc and defining "BOOST_TEST_DYN_LINK=1" on all platforms for
> shared linking. This makes the behaviour consistant on all platforms
> which means you'll get similar errors on all platforms...
> And also adding the missing usage requierements without nothing will
> work at all :-))

You also need to use <dll>... instead of <lib>.... I think

> > 1. What are the instructions for using Boost.Test DLL on Windows?

Here are some extracts from docs I an working on:

Building dynamic library
First let's clarify that by dynamic library here (and further in the
documentation) we mean dynamically loaded library (alternatively it's also
called shared library). To build dynamic library you need to add
BOOST_TEST_DYN_LINK to the list of defines in makefile. Note that the same
flag BOOST_TEST_DYN_LINK needs to be defined during test module compilation
for it to successfully link with dynamic library.

...

The supplied test runners

Design the supplied test runners is based on rationale to simplify users
experience in most common cases. No wonder result is a bit contrived, right
;)? The "source" of the complications is the word "common" above. Let's
consider different usage scenarios and the options the UTF supply in each
case.

  a.. The UTF is built as static library and linked with test module built
as executable or "included" version of UTF is used
  b.. The UTF is built as dynamic library and linked with test module built
as executable
  c.. Both UTF and test module are built as dynamic libraries
In many regards the test runner implementations works similar in all the
cases. For example return code generation follows the same logic. You will
notice in next section though that usage choice affects also required
interface of test module initialization routine.

Static library or "included" Framework

  Statically build version on the UTF and "included" header supply the test
runner in a form of free function unit_test_main with the following
signature:

int unit_test_main( int argc, char* argv[] );

  In addition in default configuration the test executable entry point
function main() is supplied that does nothing more than just invoke test
runner function. In case if this is for any reason undesirable you need to
define flag BOOST_TEST_NO_MAIN during build (either library in case of
static library or the executable itself in case of "included" version).

  If you compare with the dynamic library case you will notice that you don't
need to supply test module initialization routine as an argument to this
function. Instead it's defined as an external function with fixed name in
user's code.

Dynamic Library

  Dynamically build version on the UTF supplies the test runner in a form of
free function unit_test_main with the following signature:

int unit_test_main( bool (*init_unit_test_func)(), int argc, char* argv[] );

  Unlike static library case, function main() implementation couldn't reside
in a library code for portability reasons. Instead it's supplied as part of
unit_test.hpp header and included in case if BOOST_TEST_MAIN or
BOOST_TEST_MODULE flags are defined during compilation, while
BOOST_TEST_NO_MAIN is not. Notice that if multiple test files in test module
include unit_test.hpp, BOOST_TEST_MAIN/ BOOST_TEST_MODULE should be defined
only in one of them.

  Also in this case you need to supply the pointer to the initialization
routine as an argument to the test runner function (since in general case
dynamic library implementation couldn't have any undefined symbols
reference).

...

Test module initialization

  There are two tasks that may need to be done by users before actual
testing could start:

  1.. Test tree need to be built (unless you are using automatic
registration facilities)
  2.. Any custom user initialization needs to be performed. That includes
initialization of the code under test and custom tune-up of the UTF
parameters (for example log or report output streams redirection).
  The UTF dedicate single function for this purpose called test module
initialization routine. Alternatively in you could employ global fixtures.
For more details, including differences in two approaches, check the
fixtures section.

  The UTF require the test module initialization routine to be defined be
the users. In case if static library or included version is used, the UTF
enforces both function signature and function name. In case if dynamic
library is used only function signature is enforced by the UTF in general
case. But supplied test runners also enforce the same function name (as the
one required by former case) in case if you wish to auto-generate function
main() body.

  In many cases you don't need to do any custom initialization and test tree
construction is automated. In this case you don't really need the
initialization function and the UTF provides a way to automatically generate
empty one.

  In older versions of the UTF the test tree construction was always manual.
Later versions introduced an ability to employ automatically registering
test cases and test suites. In new design original initialization function
signature became inconvenient and unnecessary unsafe. So an alternative
initialization function signature was introduced. This change is not
backward compatible though. So for now the UTF is still using original
initialization function signature by default. To switch to use alternative
new one you need to define BOOST_TEST_ALTERNATIVE_INIT_API both during
static library build, if you choose to have one, and during test module
build. The plan for the next release is to switch default from the original
to new signature. Ultimately old initialization function signature will be
deprecated and removed.

Original (default) initialization function signature and name

  In original design of the UTF user is required to implement the function
with the following specification:

boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )

While this function was originally designed to initialize and return master
test suite, in current version of the UTF the result value of this function
is ignored and accordingly null value is not considered to be an error. So
don't return constructed test suites. Instead register them in master test
suite using regular test suite add interface. The only way to report
initialization error is to throw a framework::setup_error exception. Pair of
arguments argc, argv presents command line arguments specified during test
module invocation. It's guarantied that any framework-specific command line
arguments are excluded.

Alternative initialization function signature and name

  In alternative initialization design the UTF user is required to implement
function with the following specification:

bool init_unit_test()

The result value of this function indicates whether or not initialization
was successful. To register test cases or test suites in a master test suite
use regular test suite add interface. To access command line arguments use
framework::master_test_suite().argc and framework::master_test_suite().argv.
It's guarantied that any framework-specific command line arguments are
excluded. Note that this interface for runtime parameter access is
temporary. It's planed to be updated once runtime parameters support rework
is completed.

Automatic generation of test tree initialization function

To automatically generate empty initialization function you need to define
BOOST_TEST_MAIN before including boost/test/unit_test.hpp header. The value
of this define is ignored. Alternatively you could define BOOST_TEST_MODULE
to be equal to any string (not necessarily in quotes). This macro will cause
the same result as BOOST_TEST_MAIN, and in addition the value of this macro
will became the name of the master test suite. Note though that for test
module consisting from multiple test files you need to define theses macros
only in a single file. Otherwise you will generate multiple instances of the
initialization function.

Dynamic Library

  Due to some portability limitation users of dynamically build library are
required to employ new alternative initialization function signature.
BOOST_TEST_MAIN/BOOST_TEST_MODULE flags still could be used to generate
empty instance of initialization function. Notice though that these flags
also govern inclusion of function main default implementation into test file
body. It means that if you wish to implement either of them manually, you
couldn't define above flags and are required to implement both function
main() and initialization function (on plus side: in this case you are not
required to comply to initialization function name).

> My main questions:
> - Is it really necessary to have two different setup method for
> Boost.Test ? One for shared and one for static linking ?

In short - yes

> - can we provide a (maybe special) target which will automagically
> provide a "main" when linking to the shared libraries ?

Please read above and let me know if your questions still persist.

Gennadiy


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk