Refactoring a library for header-only or linked library?

I am considering refactoring a (potential Boost) library separating declarations and definitions into two sets of files with the objective of reducing compilation times and allow it to be used as header-only or linking with a pre-built library. Is there is best/Boost way of doing this? Is there a Boost library that I should use as a model? ASIO? Should I call the definition files .cpp or .ipp? Should definition files go in libs/src or in boost/? How should I control the header-only/library switch? View and suggestions? Thanks Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

I am considering refactoring a (potential Boost) library separating declarations and definitions into two sets of files with the objective of reducing compilation times and allow it to be used as header-only or linking with a pre-built library.
Is there is best/Boost way of doing this?
Is there a Boost library that I should use as a model? ASIO?
Should I call the definition files .cpp or .ipp? The definitions should be on a header file and .ipp or .hpp is good for me. Boost.Chrono uses .hpp header files. Should definition files go in libs/src or in boost/? Boost.Chrono includes them in boost/chrono/detail/inlined directory.
Le 01/04/12 10:54, Paul A. Bristow a écrit : libs/xxx/src should not work as an installer don't need to install this directory.
How should I control the header-only/library switch?
Boost.Chrono uses a macro to BOOST_CHRONO_HEADER_ONLY as the goal was to make the library header-only. #ifdef BOOST_CHRONO_HEADER_ONLY #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas #else #include <boost/chrono/detail/inlined/chrono.hpp> #endif The config.hpp file contains #ifdef BOOST_CHRONO_HEADER_ONLY #define BOOST_CHRONO_INLINE inline #define BOOST_CHRONO_STATIC inline #define BOOST_CHRONO_DECL #else #define BOOST_CHRONO_INLINE #define BOOST_CHRONO_STATIC static ... #endif Note that this has some relation with the macros BOOST_XXX_STATIC_LINK and BOOST_XXX_DYN_LINK which are exclusive. Your goal been different the macro should be named differently. In addition what is the default also need to be taken in account. In the case of Boosy.Chrono I prefered to state explicitly the intent of the User via BOOST_CHRONO_HEADER_ONLY even if it could be deduced when BOOST_CHRONO_STATIC_LINK and BOOST_CHRONO_DYN_LINK are not defined. HTH, Vicente

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Vicente J. Botet Escriba Sent: Sunday, April 01, 2012 3:59 PM To: boost@lists.boost.org Subject: Re: [boost] Refactoring a library for header-only or linked library?
I am considering refactoring a (potential Boost) library separating declarations and definitions into two sets of files with the objective of reducing compilation times and allow it to be used as header-only or linking with a
Le 01/04/12 10:54, Paul A. Bristow a écrit : pre-built library.
Is there is best/Boost way of doing this?
Is there a Boost library that I should use as a model? ASIO?
Should I call the definition files .cpp or .ipp?
Should definition files go in libs/src or in boost/? Boost.Chrono includes them in boost/chrono/detail/inlined directory.
The definitions should be on a header file and .ipp or .hpp is good for me. Boost.Chrono uses .hpp header files. libs/xxx/src should not work as an installer don't need to install this directory.
How should I control the header-only/library switch?
Boost.Chrono uses a macro to BOOST_CHRONO_HEADER_ONLY as the goal was to make the library header-only.
#ifdef BOOST_CHRONO_HEADER_ONLY #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas #else #include <boost/chrono/detail/inlined/chrono.hpp> #endif
The config.hpp file contains
#ifdef BOOST_CHRONO_HEADER_ONLY #define BOOST_CHRONO_INLINE inline #define BOOST_CHRONO_STATIC inline #define BOOST_CHRONO_DECL
#else #define BOOST_CHRONO_INLINE #define BOOST_CHRONO_STATIC static ... #endif
Note that this has some relation with the macros BOOST_XXX_STATIC_LINK and BOOST_XXX_DYN_LINK which are exclusive.
Your goal been different the macro should be named differently. In addition what is the default also need to be taken in account.
In the case of Boosy.Chrono I prefered to state explicitly the intent of the User via BOOST_CHRONO_HEADER_ONLY even if it could be deduced when BOOST_CHRONO_STATIC_LINK and BOOST_CHRONO_DYN_LINK are not defined.
Thanks for this advice. Better advice might have been "Don't try this at home!" ;-) The complexity of templates and their instantiation means that breaking the ODR proves unavoidable. So I am reverting to the inclusion model :-( But thanks anyway. Paul --- Paul A. Bristow, Prizet Farmhouse, Kendal LA8 8AB UK +44 1539 561830 07714330204 pbristow@hetp.u-net.com

Le 12/04/12 16:14, Paul A. Bristow a écrit :
Thanks for this advice. Better advice might have been "Don't try this at home!" ;-)
The complexity of templates and their instantiation means that breaking the ODR proves unavoidable.
So I am reverting to the inclusion model :-(
But thanks anyway.
Hi, I agree that a library must be either header-only or not, and that the user shall no choose. I did this with the intention to move to a header-only library, but Boost.Systems didn't move, so now Boost.Chrono is in an unstable situation. I will add a note for the next release explaining that this is not a configuration option for the end user, but for the one installing Boost. To be coherent the definition of BOOST_HEADER_ONLY can not be used at the command line, but the boost/chrono/config.hpp file must be changed instead to avoid ODR. Thanks for making me think a little more on this complex design. Best, Vicente
participants (2)
-
Paul A. Bristow
-
Vicente J. Botet Escriba