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

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.

Related

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.

C++ import library by source

I'm new to C++ and wonder if it is good practice to include a library by source code. If it is, what would be the best way to achieve this? Just copying in a subfolder and using include?
In my special case, I have written a small library and I'm going to use it on two different microprocessors. Compiling the library separately, copying all headers and using this "package" seems to be overkill for me.
Compiling the library separately is what should be done.
It's not that overkill either : you're just compiling the .o files for your library, then wrapping them in an archive and handling that archive around.
Normally libraries are used as libraries because it is much easier and comfortable that way. If you are using dynamic libraries (.dll or .so) things get even better because you can replace libraries on the fly and things should continue to work smoothly.
You decided to use code repositories instead of libraries which means probably more work for you. If you are happy this way that's OK, but just make sure you do not break any license, some lgpl packages (like Qt) clearly
require their libraries to be linked dynamically.
The best way to do this: hard to say but in your place I would probably use git and include the libraries as submodules.
Just #includeing source code is a bad idea since it means just to copy the code into your own, things can go wrong that way. For example if there is a static variable somewhere in the library code and the same named static variable in your code you will have a conflict.
Instead you should probably compile the library separately and link it, possibly the same way as you would do anyway (ie you build the library and then you link with that library). But the light weight alternative would be just to compile the additional C++ files and then link the object files together to an executable. Details on how you do that is compiler specific.
There's valid reasons for including the library source in this way, for example if your project needs to modify the library during development it would be easier to do so if the rebuilding of the library is done as a part of the build process of the project. With a well designed build process the library shouldn't have to be rebuilt unless there are actual changes to it.
The value of a library is in part that you link it more often than you compile it, leading to a net saving.
If you control all the source, then whatever build process works best for you is fine.
I agree with πάντα ῥεῖ but I'll also add that the reason it is bad practice is because the compiled library can be stored in your computer in a common location and used by tons of different programs, thereby reducing the amount of data your computer has to store, in memory as well as RAM(if more than one running program uses the same library). An example is openGL which is a library that many games use and is probably already in your system somewhere. If you use windows, software installers link up these libraries to their programs and add them if you don't have them. If you use linux, you will be notified if libraries are missing and prompted to install them. All of that aside, you can, technically use un-compiled libraries but that introduces a number of potential licensing problems as well as additional problems with THEIR dependencies.
By copying source code to other projects and "mixing" it with other source code will stop this library from being a "library". Later on you will be tempted to make a small change in one copy (for CPU) or fix a bug and forget to do the same in the other copy.
There might be additional consideration but you should try to keep the code in one place. Do not Repeat Yourself (DRY) is a very strong and fundamental principal of software engineering with many benefits.

Is it correct to manually copy header .hpp files into my project_root/boost library?

I was reading the documentation and found it quite vague:
To compile anything in Boost, you need a directory containing the boost/ subdirectory in your #include path.
Since all of Boost's header files have the .hpp extension, and live in
the boost/ subdirectory of the boost root, your Boost #include
directives will look like:
#include <boost/whatever.hpp>
or
#include "boost/whatever.hpp"
depending on your preference regarding the use of angle bracket
includes.
Am I supposed to always create a subdirectory named "boost" in my project root and then manually copy each .hpp file I need from my boost installation/header directory into the project_root/boost directory?
I could also see telling Eclipse to automatically scan my boost root installation/include directory for the headers, thus avoiding the manual copy. Also, I could see making a soft link to the boost root installation/include directory into the project boost folder so as to include everything without having to make a single manual copy.
One difference I see is including the boost header files in my projects versus not including them in my project and referring to them externally
I am not sure which of these strategies is right. Which is the best practice here?
The correct option for smallish development projects is probably the one you suggest here:
"I could also see telling Eclipse to automatically scan my boost root installation/include directory for the headers, thus avoiding the manual copy." (Specifically, adding your boost installation's include directory to your compiler/Eclipse search path.)
That is what the boost documentation means by having a directory containing boost/ in your #include path.
For small individual projects, you don't really want to be messing around creating hand-built links to boost includes for each project if your boost installation rarely changes, unless that's a part of your broader build strategy across projects. I've worked in organisations where this is done for good reasons, basically to enable you to set up different build instances pointing at different versions of boost (or other third party libraries) by just switching some symbolic links, rather than messing around with the make dependencies and paths.
So setting up sym links to boost's include, lib, etc. inside your project might be an option if you want that level of flexibility.
However, manually copying the boost header files into your project each time is not a good way to do it.
It's unusual,- and certainly not good practice-, to copy library headers to your projects, and it's not necessary at all.
Use the -I option to tell the compiler which additional pathes to search for include files.
Concerning Eclipse CDT, you can add the additional include pathes using the C++-Build Options of your project properties.
Referring to them externally.
Copying library files into application projects is nothing but copy-n-pasting code at a higher level. Don't do it. It typically leads to an extremely unstructured software architecture. You should even take the opposite direction: modularise your project's own code to create your own internal libraries, which your project then treats exactly like Boost libraries or the standard library. This is what your application project's files should look like:
#include <your_own_library/whatever.h>
#include <boost/whatever.hpp>
#include <string>
class ApplicationSpecificClass
{
// ...
};
Thinking in terms of libraries and APIs will improve your software-engineering skills significantly. It only requires that you learn more about your build environment and the options featured by your compiler and linker (both to create libraries and to use them). Learning how to use Boost libraries is a good start, because most of them are header-only libraries, which makes everything easier.

Lib Files and Defines

I'm using a couple of external libraries and I'd rather not have to include all their source and header files in my main source directory or in my project file. One option would be to compile the libraries as lib files and link them like that. However I'm not sure the defines get evaluated before or after the lib file gets created (which one is it?). If it's before then obviously I can't just pack them because they might not work properly on different compilers or systems.
So if I can't pack the libraries as lib files, is there any way for me to link in the c or cpp source files? Probably not, since they would have to be compiled first, but maybe I'm wrong.
Edit: Here's a follow-up question, based on answers. Do you think it'd be too much of a hassle to have a makefile that creates the lib files? I'd still rather not add the sources to my project or in my source directory.
Library is a binary file, so all defines obviously already in.
Just to make order, defines are evaluated as 1st stage of compilation process - the step is called preprocess. At this stage, for each cpp files created one file containing all #include'ed in it files recursively and all macros are evaluated.
Any way 3rd party should not depend on your compilation flags with one exception - release/build lib. Only in this case you need 2 versions of 3rd lib.
As regarding to question if to compile 3rd party libs once or each time while compiling your code it depends. If you are doing it only for itself than do what looks an easies way for you, but if we're talking about development team and the project to be maintain for a long time, than more things are to be considered.
SO we're talking about some solid solution for a team and we want to compile library several times.
In this case I personally strive to compile 3rd part library once and use it many times. This reduces compilation times for each build for each developers, which means faster development.
Nice, but where you hold these libs. I like phisycal separation - 3rd party library and my code not in same tree. This can avoid some not intentional errors. A good build system, and most of time it's mandatory, should be re-buildable. This means that if you checkout your code after year, you can compile and receive exactly same binaries.
Once I used some external read only tree on my machine. This tree was managed only by me.
To make my sources re-buildable, each next version of 3rd party library put in direcoty containing it's version and my source tree was updated to point to this point. If you build on several machines, than the read only tree should be visible on all these machines.
Additioanal solution is to check if your SCM tool (I suppose you use one) gives you some ability to combine several sub-tries from repository in one checkhout. For each 3rd party library there's one sub-tree. This way 3rd party libraries are available on all machines your build. I currenly use these method on subversion - it's called svn:external. On CVS AFAIK it's called cvs modules. Additional advantage that the libraries are managed by source control system, so you can track all changes done to 3rd party libs.
defines get evaluated even before compiling. They are dealt with by the pre-processor, that prepares the code for the compiler to use. So yes, they are evaluated before the libraries are created.
You can't link against source code. You can only link with object files, static libraries, or dynamic libraries (shared object files/DLLs).
Using dynamic linking can be a good option, especially if the externals are large and/or you'll be using them in many executables.

How do you deal with large dependencies in Boost?

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!