How do you deal with large dependencies in Boost? - c++

Boost is a very large library with many inter-dependencies -- which also takes a long time to compile (which for me slows down our CruiseControl response time).
The only parts of boost I use are boost::regex and boost::format.
Is there an easy way to extract only the parts of boost necessary for a particular boost sub-library to make compilations faster?
EDIT: To answer the question about why we're re-building boost...
Parsing the boost header files still takes a long time. I suspect if we could extract only what we need, parsing would happen faster too.
Our CruiseControl setup builds everything from scratch. This also makes it easier if we update the version of boost we're using. But I will investigate to see if we can change our build process to see if our build machine can build boost when changes occur and commit those changes to SVN. (My company has a policy that everything that goes out the door must be built on the "build machine".)

First, you can use the bcp tool (can be found in the tools subfolder) to extract the headers and files you are using. This won't help with compile times, though. Second, you don't have to rebuild Boost every time. Just pre-build the lib files once and at every version change, and copy the "stage" folder at build time.

Unless you are patching the boost libraries themselves, there is no reason to recompile it every time you do a build.

We're using Boost, but we only include object files for those types that we actually use. I.e., we build our own static library with a bunch of home-grown utilities and include those parts of Boost that we find useful. Our CMakeLists.txt looks something like this (you should be able to load this in CMake, if you adjust SOURCES accordingly.)
project( MyBoost )
set(SOURCES
boost/regex/src/c_regex_traits.cpp
boost/regex/src/cpp_regex_traits.cpp
boost/regex/src/cregex.cpp
boost/regex/src/fileiter.cpp
boost/regex/src/icu.cpp
boost/regex/src/instances.cpp
boost/regex/src/posix_api.cpp
boost/regex/src/regex.cpp
boost/regex/src/regex_debug.cpp
boost/regex/src/regex_raw_buffer.cpp
boost/regex/src/regex_traits_defaults.cpp
boost/regex/src/static_mutex.cpp
boost/regex/src/usinstances.cpp
boost/regex/src/w32_regex_traits.cpp
boost/regex/src/wc_regex_traits.cpp
boost/regex/src/wide_posix_api.cpp
boost/regex/src/winstances.cpp
)
add_library( MyBoost STATIC ${SOURCES})

Precompiled headers are the word of the day! Include the boost headers you need in your precompiled header - tada!

Related

How do I properly integrate a modular boost build into my CMake project using FetchContent?

CMake FetchContent is a great way to manage build dependencies, by integration the dependency into your build and build it from source along with your own sources.
I would like to do this with Boost, too. I am encouraged by the fact that CMake support for Boost is steadily improving.
Of course since Boost is a large package, and one rarely uses all Boost libraries in a project, it would be rather wasteful to pull the entire Boost sources into one's own build. Given the modularity of the Boost project, using git submodules, it would be much more intelligent and efficient to only fetch the sources for the libraries actually used, and FetchContent supports this via its GIT_SUBMODULES option.
However, this doesn't seem to cater for dependencies between the Boost libraries. Do I need to handle this manually, or is there a more intelligent solution?
Furthermore, how do I control installation in this scenario? Many Boost libraries are header-only, and I don't want the headers included in my installation, since I'm only using them for my build. Is there a way to tell CMake that I don't want anything installed from what I fetch with FetchContent?
I have read Craig Scott's book, and of course the CMake documentation, but there's not much information about this sort of problem.
But maybe I'm trying something that I shouldn't be doing. Have others tried this, and can show me how it's done properly?

Strategy to omit unused boost src files while shipping source code

I'm using
#include <boost/numeric/ublas/matrix.hpp>
in fact that's the only boost file I've included. Now I want to ship the source code and I was hoping not have to include all hundreds of MBs of boost_1_67_0.
How to deal with this issue?
This is simply something you would add to the list of build-dependencies of your C++ source code.
This kind of dependency could be made technically "bound" to your source code distribution via your version control system. In Git, for example, you could link to certain Boost libraries via a sub-module that links to their official git mirrors (github.com/boostorg as of this writing). When cloning your repository, it would then be an option to take in the Boost libraries at the same time.
Though, taking the size of the Boost headers into consideration, having them installed as a system-wide library, might be less complicated. Tools like CMake can help you write the logic for header-inclusion so you can support different header locations.
Of course, if what you seek is to create a fully isolated copy of your source code, the approach to bake all code into one massive header-file might be an option as well (but it should not be necessary).
You can preprocess the one header file you need, which will expand all its #includes:
c++ -E /usr/include/boost/numeric/ublas/matrix.hpp -o boost_numeric_ublas_matrix.hpp
Be aware though: this will expand even your system header files, so it assumes your users will build on the same platform. If they might compile on different platforms, you should simply omit the Boost code from your project and let the users install it themselves in whatever manner they choose.

choose to build library or executable in cmake

I'm building a library in c++ for which I generate project with CMake.
However, I don't know how to write a good CMakeLists.txt at the top directory of the library.
In fact, actually it works if I want to simply include the library in another project (adding library, linking sources, etc...), but I want that if I generate the library itself without other project, it generate a demo project provided by the library.
So I would like a CMakeLists that
link the library in the case of an inclusion in a project
build a demo in the case of the CmakeLists is used as the top cmakelists.
My first idea is to search if "project(xxx)" has already been called, but I don't know if this is a good idea. As I don't really know what is the good practice about this I have real difficulties to find information in the documentation.
A quick way to detect if your current project is also the top-level project is by inspecting PROJECT_SOURCE_DIR and CMAKE_SOURCE_DIR:
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
message("You are building stand-alone!")
endif()
But note that this might not be the best solution to your problem. Allowing libraries to be pulled into third-party builds like this requires explicit support from both your library and the enclosing build.
Alternatively, you can build both projects separately, but provide proper packaging for your library to make it easy to integrate. This approach is usually more flexible, as it gives your clients the freedom to choose when and how they want to build your library before pulling it into their build.

Boost C++ libraries installation

I have just downloaded the boost libraries from the boost website and extracted them to my desktop. I was hoping to just have a quick look at them and have them installed on my machine and perhaps use them in the future when I am more accustomed to C++.
When I extracted it, I was confused with all of the extracted files. There is all of the headers in the boost directory but tutorials mention running bootstrap.bat (I'm using Windows).
So I am asking this: do I simply extract the headers to my compilers include directory like normal to get boost up and running or do I need to do something else?
As I understand it from searching about, apparently "most" of boost is just templates and can be used simply by including the headers, but what about the rest?
Am I totally barking up the wrong tree?
Thanks for any help
Since you mentioned you run Windows, take a look at this automated installer:
► http://www.boostpro.com/download/
Also, some general advice:
do I simply extract the headers to my compilers include directory
No! Do not pollute your compiler's includes with third-party includes; make a separate directory specifically for a particular library. You'll then need to tell your specific IDE in what directory it can find the library headers.
I usually use boostpro's installer, it is less work. I vaguely remember having to set up the BOOST_ROOT environment variable on one of my systems to use it.
The libraries that contained compiled source should be included in the installer.
If you don't use the installer (or don't set up your build correctly), and try to use the libraries that need it you will likely get some linker errors when you try and compile your program. Usually if you take those linker errors and plop them in google it tells you pretty quick which libraries you need to include in your build system. I use CMake for that and have been very happy..
Just add the root boost directory to include paths of your compiler/IDE (so if you have Boost extracted to C:\Boost, the compiler will use that path, not C:\Boost\boost).
Don't do any copying of the boost folder to your compiler's include directory, because it may make upgrading Boost harder in the future.
Also if you plan to use any of boost's compiled libraries, add Boost's lib directory to compiler's library search paths. Configuring the compiling step is a matter of putting the right toolset parameter to boost's build tool. If you have your command line environment configured properly, bootstrap should run and compile the builder without any problems, and the Boost builder should properly detect your toolset, so no parameters will be necessary.
As you do such configuration only once every time you do a clean install of your favorite compiler, it's not as hard or daunting as it seems.

How to include only BOOST smart pointer codes into a project?

What are best practices to include boost smart pointer library only without adding all boost libraries into the project?
I only want boost smart pointer library in my project and I don't want to check in/commit 200 MB source codes (boost 1.42.0) into my project repository just for that. What more, my windows mobile project itself doesn't even reach 10% of that size!
For just the smart pointer library, you have two options.
Copy the headers you include in your source files (shared_ptr.hpp, etc.). Then copy over additional files until the project builds (make sure to maintain the directory structure).
Use the boost bcp utility. For larger subsets, this tool saves a ton of time.
The former will make sure the fewest number of files possible gets added your project. The latter is much faster for any substantial subset of boost, but it will likely include many files you don't need (compatibility headers for platforms your program doesn't support).
Just check in the folder containing the code you want? Try deleting/moving/renaming "everything else" and see what external dependencies the smart pointer library has, probably not many. I'm almost positive it doesn't require any built code (i.e. libraries), so just checking in all of the headers that get included seems like the way to go.