[Boost-bugs] [Boost C++ Libraries] #1094: Finding the correct library to link (feature request for pkg-config support)h

Subject: [Boost-bugs] [Boost C++ Libraries] #1094: Finding the correct library to link (feature request for pkg-config support)h
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2007-07-16 17:41:28


#1094: Finding the correct library to link (feature request for pkg-config
support)h
-------------------------------+--------------------------------------------
 Reporter: rleigh_at_[hidden] | Type: Bugs
   Status: new | Milestone: To Be Determined
Component: None | Version:
 Severity: Problem | Keywords: pkg-config linking library naming
-------------------------------+--------------------------------------------
 This bug report is a feature request for the addition of pkg-config
 support to Boost, in order to provide a simple, reliable, platform-
 independent mechanism for discovering if the Boost libraries are
 installed, what they are called, where they are installed, and how to link
 with them. This is currently not possible to achieve. A detailed
 rationale and an example for how to implement this follow.


 I make use of several Boost libraries in my schroot program
 (svn://svn.debian.org/svn/buildd-tools/trunk/schroot).

 This project, like many, utilises GNU Autoconf and Automake for its
 build system. I need to determine how to link with the Boost
 libraries in order to build the programs in the project. This is an
 issue for many projects which want to link with a Boost library. Note
 that calling bjam is not a possibility here; it may not be installed, and
 most projects are not using bjam, especially if boost is just one of many
 libraries being used.


 To illustrate my problem:

  ls -l /usr/lib/libboost_regex-*.so /usr/lib/libboost_program_options-*.so
 lrwxrwxrwx 1 root root 45 2007-07-08 11:48 /usr/lib/
 libboost_program_options-gcc41-1_34.so -> libboost_program_options-gcc41-
 1_34.so.1.34.0
 lrwxrwxrwx 1 root root 48 2007-07-08 11:48 /usr/lib/
 libboost_program_options-gcc41-mt-1_34.so -> libboost_program_options-
 gcc41-mt-1_34.so.1.34.0
 lrwxrwxrwx 1 root root 41 2007-07-08 11:48 /usr/lib/
 libboost_program_options-mt.so -> libboost_program_options-gcc41-mt-
 1_34.so
 lrwxrwxrwx 1 root root 38 2007-07-08 11:48 /usr/lib/
 libboost_program_options-st.so -> libboost_program_options-gcc41-1_34.so
 lrwxrwxrwx 1 root root 35 2007-07-08 11:47 /usr/lib/libboost_regex-gcc41-
 1_34.so -> libboost_regex-gcc41-1_34.so.1.34.0
 lrwxrwxrwx 1 root root 38 2007-07-08 11:47 /usr/lib/libboost_regex-gcc41-
 mt-1_34.so -> libboost_regex-gcc41-mt-1_34.so.1.34.0
 lrwxrwxrwx 1 root root 31 2007-07-08 11:47 /usr/lib/libboost_regex-mt.so
 -> libboost_regex-gcc41-mt-1_34.so
 lrwxrwxrwx 1 root root 28 2007-07-08 11:47 /usr/lib/libboost_regex-st.so
 -> libboost_regex-gcc41-1_34.so

 Unlike every other library on my system, the Boost libraries have the
 compiler (gcc41) and threading model (mt|st) and so on embedded *in
 the library name*. This makes it impossible to discover in an
 automatic fashion. Since my project is free software anyone can download
 and build, I don't know what the compiler/toolchain will be, let alone
 what abbreviation Boost has chosen for it. I expect that Autoconf
 will set up such things appropriately; my code is relatively compiler-
 agnostic, but I can't predict the Boost library names without help.

 The only means I have are the libboost_program_options-mt.so,
 libboost_program_options-st.so (and so on for all the libraries)
 symbolic links which the Debian maintainer has helpfully provided.
 However, these are not portable, and are so not a good solution. They
 are, however, the only available solution at the moment.


 To further show the problem I am having, this is part of my
 configure.ac Autoconf template:

 ---configure.ac----
 AC_CHECK_HEADERS([tr1/memory])

 AC_CHECK_HEADERS([boost/shared_ptr.hpp],, [
   if test $ac_cv_header_tr1_memory = yes; then
     :
   else
     AC_MSG_ERROR([Boost.shared_ptr (Boost C++ Libraries) is not installed,
 but is required by schroot])
   fi])

 AC_CHECK_HEADERS([tr1/tuple])

 AC_CHECK_HEADERS([boost/tuple/tuple.hpp],, [
   if test $ac_cv_header_tr1_memory = yes; then
     :
   else
     AC_MSG_ERROR([Boost.Tuple (Boost C++ Libraries) is not installed, but
 is required by schroot])
   fi])

 AC_CHECK_HEADERS([boost/format.hpp],, [AC_MSG_ERROR([Boost.Format (Boost
 C++ Libraries) is not installed, but is required by schroot])])
 AC_CHECK_HEADERS([boost/program_options.hpp],,
 [AC_MSG_ERROR([Boost.Program_options (Boost C++ Libraries) is not
 installed, but is required by schroot])])
 AC_CHECK_HEADERS([boost/type_traits.hpp],, [AC_MSG_ERROR([Boost.TypeTraits
 (Boost C++ Libraries) is not installed, but is required by schroot])])

 AC_MSG_CHECKING([for boost::program_options::variables_map in
 -lboost_program_options-st])
 saved_ldflags="${LDFLAGS}"
 LDFLAGS="${LDFLAGS} -lboost_program_options-st"
 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <boost/program_options.hpp>],
 [boost::program_options::variables_map::variables_map dummy()])],
                [AC_MSG_RESULT([yes])
                 BOOST_LIBS="${BOOST_LIBS} -lboost_program_options-st"],
                [AC_MSG_RESULT([no])
                 AC_MSG_FAILURE([libboost_program_options (Boost C++
 Libraries) is not installed, but is required by schroot])])
 LDFLAGS="${saved_ldflags}"

 AC_MSG_CHECKING([for
 boost::program_options::options_description::options() in
 -lboost_program_options-st])
 saved_ldflags="${LDFLAGS}"
 LDFLAGS="${LDFLAGS} -lboost_program_options-st"
 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <boost/program_options.hpp>],
 [boost::program_options::options_description testgrp("test group");
                                 bool notused = testgrp.options().empty();
 ])],
                [AC_MSG_RESULT([yes])
                 BOOST_PROGRAM_OPTIONS_DESCRIPTION_METHODS="current"],
                [AC_MSG_RESULT([no])
                 BOOST_PROGRAM_OPTIONS_DESCRIPTION_METHODS="old"])
 LDFLAGS="${saved_ldflags}"
 AH_TEMPLATE(BOOST_PROGRAM_OPTIONS_DESCRIPTION_OLD, [Set if
 boost::program_options::options_description::options() is not available])
 if test "$BOOST_PROGRAM_OPTIONS_DESCRIPTION_METHODS" = "old"; then
   AC_DEFINE(BOOST_PROGRAM_OPTIONS_DESCRIPTION_OLD, 1)
 fi

 AC_MSG_CHECKING([for boost::regex in -lboost_regex-st])
 saved_ldflags="${LDFLAGS}"
 LDFLAGS="${LDFLAGS} -lboost_regex-st"
 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <boost/regex.hpp>],
                                [boost::regex("^foo[bar]$")])],
                [AC_MSG_RESULT([yes])
                 BOOST_LIBS="${BOOST_LIBS} -lboost_regex-st"],
                [AC_MSG_RESULT([no])
                 AC_MSG_FAILURE([libboost_regex (Boost C++ Libraries) is
 not installed, but is required by schroot])])
 LDFLAGS="${saved_ldflags}"

 AC_SUBST([BOOST_LIBS])

 ---configure.ac----

 As you can see, that's quite a bit of complexity. It also includes
 code to work around a backwards compatibility issue in
 Boost.Program_options. However, it needs to know the library name in
 order to link the test code, and I'm still needing to use a
 non-standard name in order to do that.


 It would be great if Boost would provide a mechanism to allow such
 discovery. Such a mechanism already exists, and is called
 "pkg-config". By installing a small file in LIBDIR/pkgconfig for each
 Boost library, the pkg-config tool or PKG_CHECK_MODULES Autoconf macro
 may be used to query this information. As an example:

 ---- boost-regex-mt.pc ----
 prefix=/usr
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib
 includedir=${prefix}/include

 Name: boost-regex-mt
 Description: Boost C++ Regular Expression Library (multi-threaded)
 Version: 1.34.0
 Libs: -L${libdir} -lboost_regex-gcc41-mt-1_34
 Libs.private: -licui18n -licuuc -lrt -lm
 Cflags: -I${includedir} -pthread
 ---- boost-regex-mt.pc ----

 You can generate this from a template:

 ---- boost-regex-mt.pc.in ----
 prefix=PREFIX
 exec_prefix=EPREFIX
 libdir=LIBDIR
 includedir=INCLUDEDIR

 Name: boost-regex-mt
 Description: Boost Regular Expression Library (multi-threaded)
 Version: VERSION
 Libs: -L${libdir} LIBRARY_NAME
 Libs.private: LIBRARY_DEPENDENCIES [for static linking]
 Cflags: -I${includedir} THREAD_OPTIONS_FOR_COMPILER
 ---- boost-regex-mt.pc.in ----

 where the capitalised names are where you would substitute in the
 system- and compiler-specific options. It looks like bjam could
 probably make this a single rule all libraries could make use of.

 For such a setup, all that configure script above could be mostly
 reduced to

   PKG_CHECK_MODULES([boost-regex-st])
   PKG_CHECK_MODULES([boost-program-options-st])


 I don't know how bjam works, but I do this with Autoconf as a file
 generated by config.status, but it could also be generated by make
 with a simple sed command. I guess you could do the bjam equivalent,
 whatever that might be. I have had a look at the sources to try to
 implement this, but I am afraid I lack the bjam expertise to do it.


 You may find much more detailed discussion of these issues at

   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=424038
   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=424666
   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=425264
   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=428419
   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=350539

 Some of these are due to Debian-specific issues (a change to the
 symlink name), but the root cause is the inability to identify the
 Boost library names in an automated fashion.


 Regards,
 Roger

 --
   .''`. Roger Leigh
  : :' : Debian GNU/Linux http://people.debian.org/~rleigh/
  `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/
    `- GPG Public Key: 0x25BFB848 Please GPG sign your mail.

--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/1094>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.


This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:56 UTC