aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/_posts/2017-01-07-building-boost.md
blob: 052bb26888dc8698dfe79506e23bd809898bfc31 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
---
title: Building Boost on Windows
excerpt: >
  This post describes the process of building Boost on Windows using either
  Visual Studio or the combination of Cygwin + MinGW-w64.
category: C++
custom_css:
  - syntax.css
---
Below you can find the steps required to build Boost libraries on Windows.
These steps tightly fit my typical workflow, which is to use Boost libraries in
CMake builds using either Visual Studio or the combination of Cygwin +
MinGW-w64.
I would expect, however, that the procedure for the latter toolset can easily
be adjusted for generic GCC distributions (including vanilla GCCs found in
popular Linux distributions).

One of the features of this workflow is that I build throwaway, "run
everywhere, record the results, and scrap it" executables more often than not,
so I prefer to link everything statically, including, for instance, C/C++
runtimes.
This is implemented by passing `runtime-link=static` to Boost's build utility
`b2`; change this to `runtime-link=dynamic` to link the runtime dynamically.

Excerpts from shell sessions in this post feature a few different commands
besides Boost's `b2` and `cmake`, like `cd` and `cat`.
They are used to hint at my personal directory layout, display various
auxiliary files, etc.
Windows' `cd`, for example, simply prints the current working directory;
Cygwin's `pwd` serves the same purpose.
`cat` is used to display files.
Windows' command prompts are denoted with `>`s at the beginning of each line;
Cygwin's — with `$`s.

Visual Studio
-------------

Statically-linked Boost libraries are built, both the debug and the release
versions of them (these are default settings).
While it is required to keep x86 and x64 libraries in different directories (to
avoid file name clashes), it's not necessary to separate debug libraries from
their release counterparts, because that information is actually encoded in
file names (the "gd" suffix).

### x86

```
> cd
D:\workspace\third-party\boost_1_61_0\msvc

> bootstrap
...

> b2 --stagedir=stage\x86  ^
    runtime-link=static    ^
    --with-filesystem      ^
    --with-program_options ^
    ...
...
```

### x64

The only important difference is that you have to pass `address-model=64` to
`b2` (notice also the different "staging" directory).

```
> cd
D:\workspace\third-party\boost_1_61_0\msvc

> bootstrap
...

> b2 --stagedir=stage\x64  ^
    runtime-link=static    ^
    address-model=64       ^
    --with-filesystem      ^
    --with-program_options ^
    ...
...
```

Cygwin + MinGW-w64
------------------

Contrary to the Visual Studio example above, it is required to store debug and
release libraries *as well as* x86 and x64 libraries in different directories.
It is required to avoid file name clashes; unlike the Visual Studio "toolset"
(in Boost's terms), GCC-derived toolsets don't encode any information (like
whether the debug or the release version of a library was built) in file names.

Also, linking the runtime statically doesn't really make sense for MinGW, as it
always links to msvcrt.dll, which is [simply the Visual Studio 6.0 runtime].

[simply the Visual Studio 6.0 runtime]: https://sourceforge.net/p/mingw-w64/wiki2/The%20case%20against%20msvcrt.dll/

In the examples below, only the debug versions of the libraries are built.
Build the release versions by executing the same command, and substituting
`variant=release` instead of `variant=debug` and either
`--stagedir=stage/x86/release` or `--stagedir=stage/x64/release`, depending
on the target architecture.

### x86

```
$ pwd
/cygdrive/d/workspace/third-party/boost_1_61_0/mingw

$ ./bootstrap.sh
...

$ cat user-config-x86.jam
using gcc : : i686-w64-mingw32-g++ ;

$ ./b2 toolset=gcc-mingw              \
    target-os=windows                 \
    link=static                       \
    variant=debug                     \
    --stagedir=stage/x86/debug        \
    --user-config=user-config-x86.jam \
    --with-filesystem                 \
    --with-program_options            \
    ...
...
```

The "user" configuration file above stopped working at some point; not sure as
to who's to blame, Cygwin or Boost.
If you see something like "`error: provided command 'i686-w64-mingw32-g++' not
found`", add ".exe" to the binary name above, so that the whole file reads
"`using gcc : : i686-w64-mingw32-g++.exe ;`".
{: .alert .alert-info }

### x64

Notice the two major differences from the x86 example:

* the addition of `address-model=64` (as in the example for Visual Studio),
* the different "user" configuration file, pointing to `x86_64-w64-mingw32-g++`
instead of `i686-w64-mingw32-g++`.

Again, as in the example for Visual Studio, a different "staging" directory
needs to be specified using the `--stagedir` parameter.

```
$ cd
/cygdrive/d/workspace/third-party/boost_1_61_0/mingw

$ ./bootstrap.sh
...

$ cat user-config-x64.jam
using gcc : : x86_64-w64-mingw32-g++ ;

$ ./b2 toolset=gcc-mingw              \
    address-model=64                  \
    target-os=windows                 \
    link=static                       \
    variant=debug                     \
    --stagedir=stage/x64/debug        \
    --user-config=user-config-x64.jam \
    --with-filesystem                 \
    --with-program_options            \
    ...
...
```

The "user" configuration file above stopped working at some point; not sure as
to who's to blame, Cygwin or Boost.
If you see something like "`error: provided command 'x86_64-w64-mingw32-g++'
not found`", add ".exe" to the binary name above, so that the whole file reads
"`using gcc : : x86_64-w64-mingw32-g++.exe ;`".
{: .alert .alert-info }

Usage in CMake
--------------

### Visual Studio

Examples below apply to Visual Studio 2015.
You may want to adjust the paths.

#### x86

```
> cd
D:\workspace\build\test_project\msvc\x64

> cmake -G "Visual Studio 14 2015" ^
    -D BOOST_ROOT=D:\workspace\third-party\boost_1_61_0\msvc                     ^
    -D BOOST_LIBRARYDIR=D:\workspace\third-party\boost_1_61_0\msvc\stage\x86\lib ^
    -D Boost_USE_STATIC_LIBS=ON    ^
    -D Boost_USE_STATIC_RUNTIME=ON ^
    ...
```

#### x64

```
> cd
D:\workspace\build\test_project\msvc\x86

> cmake -G "Visual Studio 14 2015 Win64" ^
    -D BOOST_ROOT=D:\workspace\third-party\boost_1_61_0\msvc                     ^
    -D BOOST_LIBRARYDIR=D:\workspace\third-party\boost_1_61_0\msvc\stage\x64\lib ^
    -D Boost_USE_STATIC_LIBS=ON          ^
    -D Boost_USE_STATIC_RUNTIME=ON       ^
    ...
```

### Cygwin & MinGW-w64

Examples below only apply to debug CMake builds.
Notice that, contrary to the Visual Studio examples above, debug and release
builds must be kept in separate directories.
You may also want to adjust the paths.

#### x86

```
$ pwd
/cygdrive/d/workspace/build/test_project/mingw/x86/debug

$ cmake -G "Unix Makefiles"                    \
    -D CMAKE_BUILD_TYPE=Debug                  \
    -D CMAKE_C_COMPILER=i686-w64-mingw32-gcc   \
    -D CMAKE_CXX_COMPILER=i686-w64-mingw32-g++ \
    -D BOOST_ROOT=/cygdrive/d/workspace/third-party/boost_1_61_0/mingw                           \
    -D BOOST_LIBRARYDIR=/cygdrive/d/workspace/third-party/boost_1_61_0/mingw/stage/x86/debug/lib \
    -D Boost_USE_STATIC_LIBS=ON                \
    ...
```

#### x64

```
$ pwd
/cygdrive/d/workspace/build/test_project/mingw/x64/debug

$ cmake -G "Unix Makefiles"                      \
    -D CMAKE_BUILD_TYPE=Debug                    \
    -D CMAKE_C_COMPILER=x86_64-w64-mingw32-gcc   \
    -D CMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \
    -D BOOST_ROOT=/cygdrive/d/workspace/third-party/boost_1_61_0/mingw                           \
    -D BOOST_LIBRARYDIR=/cygdrive/d/workspace/third-party/boost_1_61_0/mingw/stage/x64/debug/lib \
    -D Boost_USE_STATIC_LIBS=ON                  \
    ...
```