
On Mon, Jan 14, 2008 at 01:16:51AM -0500, Gennadiy Rozental wrote:
"Benoit Sigoure" <tsuna@lrde.epita.fr> wrote in message news:805924BB-31B0-44E8-88CE-9538D89B082C@lrde.epita.fr...
On Jan 12, 2008, at 3:26 AM, Gennadiy Rozental wrote:
Benoit Sigoure <tsuna <at> lrde.epita.fr> writes:
Thanks for your code. It grieves me that Boost.Test is the *only* library for which I have to write "special cases" only because it's not "well-behaved".
In what sence? How do you define well behaved?
What is this whole thread about? Boost.Test is non standard because it messes up your `main'
Why do you care? how does it make Boost.Test behave badly?
Normally one is able to test for the existence of a library by just calling a function inside main() or by creating an instance of a special type: #include <required_lib_header.h> int main(int argc, char* argv[]) { double a = function_from_lib(); type_in_lib object; } If this links successfully (using current compiler flags maybe after extented with -l <libname>) one can be sure that the library is properly installed. This is a very common task. That's why Autoconf provides a macro AC_TRY_LINK which expects the arguments "#include <required_lib_header.h>" and the body of main. A example of one of my configure.ac files (the last two arguments specify the code used if the linkage works or not, resp., I nested it): AC_TRY_LINK([#include <math.h>], [double f=3.14; return isnan(f);],, [AC_TRY_LINK([#include <math.h> int __isnand(double x) { return x != x; }], [double f=3.14; return isnan(f);], AC_DEFINE(NEED___ISNAND, 1, [Use own implementation of __isnand (cygwin)]))]) Beeing forced to also write int main(int argc, char* argv[]) { } is just not required for nearly all library tests and error prone. This is probably the argument of Benoit. He also wrapped AC_TRY_LINK to simplify his tests (it is necessary to test all library variants (multithreaded or not, ...) so a own macro makes sense) and expects a single header file name only. See e.g. the following excerpt of boost.m4: # BOOST_WAVE([PREFERRED-RT-OPT]) # ------------------------------ # Look for Boost.Wave. For the documentation of PREFERRED-RT-OPT, see the # documentation of BOOST_FIND_LIB above. AC_DEFUN([BOOST_WAVE], [BOOST_FIND_LIB([wave], [$1], [boost/wave.hpp], [boost::wave::token_id id; get_token_name(id);])]) There is in general no guarantee that a single header file is sufficent for a test but it worked for all other Boost libraries as well. That's why he was looking for the most simple test.
and must be used differently whether you're linking with it as a shared library or a static archive.
As you have seen in my example, it is exactly the same for both usage variants. The only difference is additional macro in makefile. But, than, link command is going to be different anyway.
No, you're wrong. There is no need to specify different link commands for shared or static libraries in general. I tried to compile your proposed test: #define BOOST_TEST_MODULE boost.m4 #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_CASE( MyCase ) { BOOST_ERROR( "expected" ); } Normally (for at least 95% of all libraries) one just adds -l <libname> to get it compile: $ g++ test.cpp -lboost_unit_test_framework /usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/crt1.o: In function `_start': (.text+0x18): undefined reference to `main' collect2: ld returned 1 exit status It works indeed well with $ g++ -DBOOST_TEST_DYN_LINK test.cpp -lboost_unit_test_framework Once I remove /usr/lib/libboost_unit_test_framework.so so that only the static library /usr/lib/libboost_unit_test_framework.a (which is a symbolic (filesystem) link to libboost_unit_test_framework-gcc41-1_34_1.a in Debian testing) exists one can also (normally) just specify -l <libname>. But I get: $ g++ -DBOOST_TEST_DYN_LINK test.cpp -lboost_unit_test_framework /tmp/ccKcB2Ps.o: In function `main': test.cpp:(.text+0x3d4): undefined reference to `boost::unit_test::unit_test_main(bool (*)(), int, char**)' /usr/lib/gcc/i486-linux-gnu/4.2.3/../../../../lib/libboost_unit_test_framework.a(framework.o): In function `boost::unit_test::framework::init(int, char**)': (.text+0x6fa): undefined reference to `init_unit_test_suite(int, char**)' collect2: ld returned 1 exit status Without -DBOOST_TEST_DYN_LINK $ g++ test.cpp -lboost_unit_test_framework it works. You're right that it is also possible to enforce using the static library (even if the shared one exists) by using different arguments: $ g++ test.cpp /usr/lib/libboost_unit_test_framework.a But in general everyone probably just uses -l <libname> and let's the compiler decide (which defaults to shared library variant if available). This normally works even if only one variant of a library is installed except with Boost.Test. Jens