Recently, I would like to study the Boost library. Most tutorials available online are based on using IDEs (such as VS/Code::Blocks), but I find it frustrating to have to open a bloated IDE just to write some test code. Today, I fiddled around and managed to compile/link code that uses the Boost library in SublimeText. I also organized the process/tools I worked with, so if others have similar needs and happen to see this article, they can save some time.
2016.11.01 Update
I used the latest version of MinGW64-GCC6.2 (x86_64-6.2.0-posix-seh-rt_v5-rev1) to compile LLVM/Clang 3.9, and then I used the compiled Clang to compile Boost1.62. The error messages that occurred when linking the Boost library in Clang are gone now.
Note: When compiling Boost with Clang, it is best to ensure that the current version of clang is compiled from the version of gcc in the current system; otherwise, when linking the static libraries produced by clang, strange issues might arise.
You can download my compiled versions here: MinGW62-GCC6.2(x86_64-6.2.0-posix-seh-rt_v5-rev1), LLVM/Clang3.9 compiled with GCC6.2 (above MinGW version), and Boost(MinGW64-GCC6.2/LLVM3.9/VC14-ALL). You can choose the version of the linked library (debug/release/static, etc.) as needed.
You can download the full compilation toolchain here.
Original Article
First, make sure that you have LLVM(clang) + GCC(MinGW)/MSVC installed on your computer (this article only writes about Clang/GCC versions)—or download my C++ toolchain (Cmake/Mingw/LLVM/Cppcheck) and add it to your system’s PATH.
I am using GCC version 6.2.0 (x86_64-posix-seh-rev1) and LLVM (Clang 3.9) version is x86_64-w64-windows-gnu (Thread model: posix).
Then, download the latest version from boost.org source code / installer.
Assuming you downloaded the source version in the previous step, after extracting it locally, there will be a bootstrap.bat
file in its directory. Executing it will automatically compile b2.exe
and bjam.exe
.
Then start compilation (using Clang/GCC/MSVC14). Here I choose to use clang:
1 | # Clang compilation |
--toolset
indicates the toolset used for compiling Boost.address-model=64
: This parameter follows--toolset
; it indicates whether the compiled version is 32-bit or 64-bit. If not specified while using VS, it defaults to 32-bit.--stagedir
: Specifies the directory where the compiled results will be stored.--link
: Indicates the type of linked library;static
means static library, whileshared
means dynamic library.--runtime-link
: Specifies the runtime linking approach;static
indicates static linkage with C/C++ runtime (/MT
and/MTd
), whileshared
denotes dynamic linkage with C/C++ runtime (/MD
and/MDd
), mixing linked libraries can cause LNK2038 error.--threading
: Specifies whether to use a multi-threaded or single-threaded library;multi
for multi-threading,single
for single-threading.--address-model
: Indicates whether to compile for 64-bit or 32-bit.--stage
: Indicates only to generate dll or lib, without generating a header file directory containing the include directory. If you need to generate an include directory with header files, use theinstall
parameter.debug
/release
: Generates debug or release versions.
Note: The version of Boost compiled by clang and gcc (x86/x64) depends on your compiler version (x86/x64), while the default for MSVC is x86. Therefore, using the above default compilation scheme, it’s not possible to compile x64-debug or x64-release in VS. The solution is to specify compiling for the x64 version of Boost while compiling:
address-model=64
.
Using any of the above will compile four versions of the lib: (multiThread-Release/multiThread-Debug/multiThread-StaticLink-Release/multiThread-StaticLink-Debug). You can download the three versions I compiled (clang/gcc/msvc) here.
It takes about tens of minutes for the compilation to complete, and afterward a Boost folder will be generated in the D drive root directory.
From the compilation parameters, we can see the generated lib and corresponding versions:
- Those starting with “lib” are the “link-static” version, while those directly starting with “boost” are the “link-shared” version.
- Versions containing “d” are debug versions, while those not containing “d” are release versions.
- Versions containing “s” are the “runtime-link-static” version; those without are “runtime-link-shared” versions.
- Versions containing “mt” are “threading-multi” versions; those without are “threading-single” versions.
For example:
1 | # Using this command will produce four files |
Copy /boost
from the Boost source into LLVM/include/
, and copy the files from the compiled D:/Boost/lib
into LLVM/lib
(or you can add the directory where the Boost source (/Boost/boost) and lib (/Boost/lib) are located to your system’s PATH, similar below).
OK, at this point, Boost is installed on your computer. If you need to customize modules, there are many tutorials online about how to compile and install Boost—just search for them.
However, compilation and linking can still be a significant issue. Many tutorials use IDEs to write Boost code, but as someone who prefers a lightweight environment, I dislike bloated IDEs, so I have to manually write the compilation and linking commands.
Let’s first test the following code:
1 | // printDirC.cc |
The command to compile this code using clang++ is:
1 | $ clang++ -o boost.exe boost.cc -I"C:\Program Files\BuildPath\LLVM\include" -static -L"C:\Program Files\BuildPath\LLVM\lib" |
Additionally, since the code above uses boost_filesystem
, we need to link the boost_filesystem
library during compilation. Since boost_filesystem
depends on boost_system
, we must also include boost_system
in the linking options.
1 | $ g++ -o printDirC.exe printDirC.cc -I"C:\Program Files\BuildPath\LLVM\include" -L"C:\Program Files\BuildPath\LLVM\lib" -libboost_system-clang39-mt-s-1_62 -libboost_filesystem-clang39-mt-s-1_62 |
Many articles online say to use -lboost_system
, but the names are not like that for the versions compiled with clang in Boost1.62.0, rather they are libboost_system-clang39-mt-s-1_62.lib
(for gcc it’s libboost_system-mgw62-mt-s-1_62.a
), and examples alike.
MinGW automatically adds the prefix lib and .a extensions when linking static libraries, while clang will only automatically add the .a extension and look for the corresponding library files in available paths.
For instance, when we write -llibboost_system-clang39-mt-s-1_62
, it would locate libboost_system-clang39-mt-s-1_62.lib
(for gcc-compiled version it is written as -lboost_system-mgw62-mt-s-1_62
, it would find libboost_system-mgw62-mt-s-1_62.lib
).
Thus, to link to the library, the library parameter (for GCC version) should be the static library file with the prefix lib and file suffix removed, and for the Clang version, it should be the file suffix removed.
The libraries in Boost that we can link to and the compilation linking parameters are as follows (here clang39
and 1_62
stand for the compiler and Boost version; I am only listing the multi-threaded static-link release version of lib):
Library | clang version linking parameter | GCC version linking parameter |
---|---|---|
boost_atomic | -llibboost_atomic-clang39-mt-s-1_62 | -lboost_atomic-mgw62-mt-s-1_62 |
boost_chrono | -llibboost_chrono-clang39-mt-s-1_62 | -lboost_chrono-mgw62-mt-s-1_62 |
boost_container | -llibboost_container-clang39-mt-s-1_62 | -lboost_container-mgw62-mt-s-1_62 |
boost_context | -lboost_context-mgw62-mt-s-1_62 | |
boost_coroutine | -lboost_coroutine-mgw62-mt-s-1_62 | |
boost_date_time | -llibboost_date_time-clang39-mt-s-1_62 | -lboost_date_time-mgw62-mt-s-1_62 |
boost_exception | -llibboost_exception-clang39-mt-s-1_62 | -lboost_exception-mgw62-mt-s-1_62 |
boost_filesystem | -llibboost_filesystem-clang39-mt-s-1_62 | -lboost_filesystem-mgw62-mt-s-1_62 |
boost_graph | -llibboost_graph-clang39-mt-s-1_62 | -lboost_graph-mgw62-mt-s-1_62 |
boost_iostreams | -llibboost_iostreams-clang39-mt-s-1_62 | -lboost_iostreams-mgw62-mt-s-1_62 |
boost_locale | -lboost_locale-mgw62-mt-s-1_62 | |
boost_log_setup | -llibboost_log_setup-clang39-mt-s-1_62 | -lboost_log_setup-mgw62-mt-s-1_62 |
boost_log | -llibboost_log-clang39-mt-s-1_62 | -lboost_log-mgw62-mt-s-1_62 |
boost_math_c99f | -llibboost_math_c99f-clang39-mt-s-1_62 | -lboost_math_c99f-mgw62-mt-s-1_62 |
boost_math_c99l | -llibboost_math_c99l-clang39-mt-s-1_62 | -lboost_math_c99l-mgw62-mt-s-1_62 |
boost_math_c99 | -llibboost_math_c99-clang39-mt-s-1_62 | -lboost_math_c99-mgw62-mt-s-1_62 |
boost_math_tr1f | -llibboost_math_tr1f-clang39-mt-s-1_62 | -lboost_math_tr1f-mgw62-mt-s-1_62 |
boost_math_tr1l | -llibboost_math_tr1l-clang39-mt-s-1_62 | -lboost_math_tr1l-mgw62-mt-s-1_62 |
boost_math_tr1 | -llibboost_math_tr1-clang39-mt-s-1_62 | -lboost_math_tr1-mgw62-mt-s-1_62 |
boost_prg_exec_monitor | -llibboost_prg_exec_monitor-clang39-mt-s-1_62 | -lboost_prg_exec_monitor-mgw62-mt-s-1_62 |
boost_program_options | -llibboost_program_options-clang39-mt-s-1_62 | -lboost_program_options-mgw62-mt-s-1_62 |
boost_python3 | -llibboost_python-clang39-mt-s-1_62 | |
boost_python | -llibboost_python-clang39-mt-s-1_62 | |
boost_random | -llibboost_random-clang39-mt-s-1_62 | -lboost_random-mgw62-mt-s-1_62 |
boost_regex | -llibboost_regex-clang39-mt-s-1_62 | -lboost_regex-mgw62-mt-s-1_62 |
boost_serialization | -llibboost_serialization-clang39-mt-s-1_62 | -lboost_serialization-mgw62-mt-s-1_62 |
boost_signals | -llibboost_signals-clang39-mt-s-1_62 | -lboost_signals-mgw62-mt-s-1_62 |
boost_system | -llibboost_system-clang39-mt-s-1_62 | -lboost_system-mgw62-mt-s-1_62 |
boost_test_exec_monitor | -llibboost_test_exec_monitor-clang39-mt-s-1_62 | -lboost_test_exec_monitor-mgw62-mt-s-1_62 |
boost_thread | -llibboost_thread-clang39-mt-s-1_62 | -lboost_thread-mgw62-mt-s-1_62 |
boost_timer | -llibboost_timer-clang39-mt-s-1_62 | -lboost_timer-mgw62-mt-s-1_62 |
boost_type_erasure | -llibboost_type_erasure-clang39-mt-s-1_62 | -lboost_type_erasure-mgw62-mt-s-1_62 |
boost_unit_test_framework | -llibboost_unit_test_framework-clang39-mt-s-1_62 | -lboost_unit_test_framework-mgw62-mt-s-1_62 |
boost_wave | -llibboost_wave-clang39-mt-s-1_62 | -lboost_wave-mgw62-mt-s-1_62 |
boost_wserialization | -llibboost_wserialization-clang39-mt-s-1_62 | -lboost_wserialization-mgw62-mt-s-1_62 |
To avoid having to manually add these while compiling, we can write all these linking parameters into ST’s build system. Note that the positions of -I
and -L
should be changed to your own Boost paths. For how to modify the SublimeText build system, you can check my previous article—Configuring SublimeText as a Lightweight IDE for C/C++.
1 | { |
Place all the static library linking parameters inside:
Mind the linking order, as the linker will first find the libraries at the front; if the preceding library depends on something from later libraries, it will cause compilation errors. For example, the boost_filename module in Boost depends on boost_system, so the linking for boost_system must come before that for boost_filename.
1 | $ clang++ -o test test.cc -std=c++11 -IC:\\Program Files\\BuildPath\\LLVM\\include -LC:\\Program Files\\BuildPath\\LLVM\\lib -llibboost_system-clang39-mt-s-1_62 -llibboost_filesystem-clang39-mt-s-1_62 |
For more discussion on linking order, you can see here, and discussions on stackoverflow, as well as GCC LD’s sensitivity to input order of dependent libraries.
Additionally, if necessary, you can use -Wl,-Bstatic
to specify that the following is statically linked, while -Wl,-Bdynamic
indicates that the following is dynamically linked.
Clang version:
1 | { |
GCC version (the only difference being using g++ for compilation and not writing the library filenames prefixed with lib (-lboost...
)):
1 | { |
Note: If the compilation is successful but it prompts that console_runner
cannot be found when running, you can download it here and place it in a directory in your PATH (e.g., MinGW/bin).
If you need to set up Boost in VS, you need to configure both win32 and x64 versions based on the x86/x64 versions compiled above in the View -> Property Manager section, so using x86/x64 in VS won’t cause errors.
You can use the following code to test the versions of the compiler and linked libraries:
1 |
|
The compilation results when using G++ and Clang are as follows: