aboutsummaryrefslogtreecommitdiff
path: root/INSTALL
blob: e6b7ef7ba68a9ab27e5b815854e7e6d6e88175d5 (plain)
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
Setup
=====

Setting Scripts
---------------

@@ Replace this section with a proper package build/install instructions when
   the package name is finalized.

@@ Interestingly INSTALL files for our packages provide instuctions how to
   build the package but not how to install it.

The "driver" scripts that you will be invoking have names in the following
form:

<tool>-<version>-<target>

Where:

<tool>     is one of 'cl' 'link' 'lib' 'mt' 'rc'
<version>  is the Visual Studio version, for example, 11, 12, 14.3, 15.0
<target>   is the compiler target, for example, 32 (x86), 64 (x86_64).

There are also the "configuration" scripts, msvc-NN/msvc-<version>-<target>,
which provide the Visual Studio/SDK location and configuration (in a way
similar to vcvars32.bat). There is also a bunch of other helper scripts that
you will not need to modify or invoke directly. It is also required to build
msvc-filter native utility using build2.

All of these scripts and utilities should reside in the same directory. In
particular, you cannot copy, say, cl-<...> to /usr/local/bin/ while leaving
the rest in some other directory -- this will not work. What you can do,
however, is create symlinks to the driver scripts in /usr/local/bin/ -- this
will work.

If you only need to make the scripts usable by a single user, then the easiest
approach is to add the script's directory to your PATH in, say, .bashrc, for
example:

export PATH=$HOME/msvc-linux:$PATH

Alternatively, if you have something like ~/bin/ that is already in PATH, then
you can simply add symlinks to the scripts there. This way you can also choose
shorter tool names, for example:

for t in cl link lib mt rc; do \
  ln -s .../msvc-linux/$t-14.2-64 ~/bin/$t-14; done

While you can modify the configuration scripts, retaining such modifications
over updates will be tedious. As a result, there are several environment
variables that you can set (e.g., in your .bashrc) to adjust some of the
common configuration values.

Currently you can override WINEPREFIX, INSTALLDIR, and SDKVERSION via the
following environment variable hierarchy (from highest to lowest precedence):

MSVC_<MAJOR>_<MINOR>_*   # MSVC_14_2_INSTALLDIR
MSVC_<MAJOR>_*           # MSVC_14_INSTALLDIR
MSVC_*                   # MSVC_INSTALLDIR

The WINEPREFIX value corresponds to the WINEPREFIX Wine environment variable
that allows one to use an alternative (to ~/.wine) root directory. You can
use it, for example, to maintain multiple Visual Studio updates (e.g., 14.1,
14.2, 14.3) which otherwise cannot coexist in a single installation.

The INSTALLDIR directory can be used to alter the Visual Studio installation
directory name (not path; the default is "Microsoft Visual Studio NN.0").
This can be used, for example, to implement an alternative multiple updates
strategy by installing them in the same Wine root but in different
directories. For details on how this value is used refer to the configuration
scripts.

The SDKVERSION value can be used to specify the Windows 10 SDK version to use.
It should be in the 10.0.NNNNN form. If it is not specified, then the latest
installed is used. Note that this value does not apply to Windows 8.1 and
earlier SDKs; those versions are hardcoded in the confguration scripts.

Note also that the below instructions include a call to a script that adds
lower-case symlinks for upper-case named headers. This normally fixes the
bulk of the issues associated #include directives that spell header names
differently compared to the actual file names. There are, however, rare
cases where a header is included using a mixed case (e.g., WlanTypes.h)
while the file name is spelled in the lower case (e.g, wlantypes.h). There
is no automated way to fix this and you will either have to adjust the
#include directive or manually create the required symlink.

Install Wine
------------

You need 1.7.55 or later. Previous versions are known not to work with Visual
Studio 14.

For Ubuntu, to install stable:

# add-apt-repository ppa:ubuntu-wine/ppa
# apt-get update
# apt-get install --no-install-recommends winbind
# apt-get install wine1.7
# apt-get install p11-kit-modules:i386 libp11-kit-gnome-keyring:i386

For Ubuntu, to install staging (into /opt/):

# add-apt-repository ppa:wine/wine-builds
# apt-get update
# apt-get install --install-recommends wine-staging

To install compatibility symlinks:

# apt-get install winehq-staging


Configure Wine
--------------

$ winecfg

If it suggests installing some stuff (Gecko, Mono), refuse. Change the
platform to Windows 7 (later version will probably also work).

64-bit link.exe from Visual Studio 14 is known not to work with Mono that
may have (still) been installed by winecfg. To remove it, run:

$ wine64 uninstaller --remove '{E45D8920-A758-4088-B6C6-31DBB276992E}'


Prepare to Copy Visual Studio
-----------------------------

Note that below we assume that you have installed Visual Studio in the default
location.

The following instructions are for mounting the VM parition on Linux host.
However, simply archiving the required directories on the running VM and
copying them to the Linux host should work as well.

Mount the VM disk (make sure it is not running) where you installed Visual
Studio. First get the second partition offset (<O>) and sector size (normally
512, as below).

# fdisk -lu .../windows-7.img

Then mount via the loopback device:

# losetup -o $((512*<O>)) /dev/loop0 ./windows-7.img
# mount -o ro /dev/loop0 /mnt

When finished copying Visual Studio, unmount and delete the loopback:

# umount /mnt
# losetup -d /dev/loop0


Copy and Setup Visual Studio 11
-------------------------------

$ mkdir -p ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 11.0"
$ cp -r "/mnt/Program Files (x86)/Microsoft Visual Studio 11.0/VC" \
  ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 11.0/"
$ cp "/mnt/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/mspdb110.dll" \
  ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/"

$ mkdir -p ".wine/drive_c/Program Files (x86)/Windows Kits"
$ cp -r "/mnt/Program Files (x86)/Windows Kits/8.0" \
  ".wine/drive_c/Program Files (x86)/Windows Kits/"

Add lower-case symlinks for upper-case named headers:

$ etc/lowercase-headers \
  ".wine/drive_c/Program Files (x86)/Windows Kits/8.0/Include"

Run the VC11 redistributable DLLs installer for both x64 and x86 from
.../VC/redist/1033/.

Add overrides for msvcr110.dll and msvcp110.dll: run winecfg, select the
"Libraries" tab, then enter the DLL name and "Add".


Copy and Setup Visual Studio 12
-------------------------------

$ mkdir -p ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 12.0"
$ cp -r "/mnt/Program Files (x86)/Microsoft Visual Studio 12.0/VC" \
  ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 12.0/"

$ mkdir -p ".wine/drive_c/Program Files (x86)/Windows Kits"
$ cp -r "/mnt/Program Files (x86)/Windows Kits/8.1" \
  ".wine/drive_c/Program Files (x86)/Windows Kits/"

Add lower-case symlinks for upper-case named headers:

$ etc/lowercase-headers \
  ".wine/drive_c/Program Files (x86)/Windows Kits/8.1/Include"

Run the VC12 redistributable DLLs installer for both x64 and x86 from
.../VC/redist/1033/.

Add overrides for msvcr120.dll and msvcp120.dll: run winecfg, select the
"Libraries" tab, then enter the DLL name and "Add".


Copy and Setup Visual Studio 14
-------------------------------

Note: 14 Update 2 (and presumably 3) requires Wine 1.9 or later (bug #34851).

Note: 14 Update 2 (and presumably 3) is known to work with Wine 1.9.7, 1.9.8
      but not 1.9.15.

Note: SDK 8.1 is only used by 14 Update 0.

$ mkdir -p ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 14.0"
$ cp -r "/mnt/Program Files (x86)/Microsoft Visual Studio 14.0/VC" \
  ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 14.0/"
$ cp "/mnt/Program Files (x86)/Microsoft Visual Studio 14.0/VC/redist/x86/Microsoft.VC140.CRT/msvcp140.dll" \
  ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/"

Remove Microsoft's "experience improvement data uploader" which crashes:

$ find ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 14.0/" \
  -name vctip.exe -exec rm -f '{}' ';'

$ mkdir -p ".wine/drive_c/Program Files (x86)/Windows Kits"
$ cp -r "/mnt/Program Files (x86)/Windows Kits/8.1" \
  ".wine/drive_c/Program Files (x86)/Windows Kits/"
$ cp -r "/mnt/Program Files (x86)/Windows Kits/10" \
  ".wine/drive_c/Program Files (x86)/Windows Kits/"

Add lower-case symlinks for upper-case named headers:

$ etc/lowercase-headers \
  ".wine/drive_c/Program Files (x86)/Windows Kits/8.1/Include" \
  ".wine/drive_c/Program Files (x86)/Windows Kits/10/Include"

Installing via the redistributable DLLs still does not work as of Wine 1.9.8.
Instead, we have to manually copy a bunch of DLLs from:

.wine/.../VC/redist/{x86 x64}/Microsoft.VC140.CRT/

And:

.wine/.../Windows Kits/10/Redist/ucrt/DLLs/{x86 x64}/

To:

.wine/drive_c/windows/{syswow64 system32}/

And add Wine overrides (run winecfg, select the "Libraries" tab, then enter
the DLL name and press "Add").

To discover the list of DLLs, run cl-14 to compile and link an executable and
then run the executable itself (see Test below): any DLL that causes an error
needs an override.

For Wine 1.7.55-1.9.8 the list is:

  api-ms-win-crt-runtime-l1-1-0.dll
  api-ms-win-crt-locale-l1-1-0.dll
  api-ms-win-crt-heap-l1-1-0.dll
  api-ms-win-crt-stdio-l1-1-0.dll
  api-ms-win-crt-conio-l1-1-0.dll
  ucrtbase.dll
  vcruntime140.dll
  msvcp140.dll

The following overrides are necessary because of some unimplemented functions:

  api-ms-win-crt-string-l1-1-0.dll
  api-ms-win-crt-time-l1-1-0.dll


Copy and Setup Visual Studio 15
-------------------------------

Note: 15 uses the same CRT runtime DLL version (140) as 14. If using together,
      then it makes sense to use versions from 15 which are claimed to be
      backwards compatible. The same probably applies to the SDK tools.

Copy VC files from Windows host. Note that the source path can look
differently, for example:

.../Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC.

$ mkdir -p ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 15.0"
$ cp -r "/mnt/Program Files (x86)/Microsoft Visual Studio 15.0/VC" \
  ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 15.0/"

Remove Microsoft's "experience improvement data uploader" which crashes:

$ find ".wine/drive_c/Program Files (x86)/Microsoft Visual Studio 15.0/" \
  -name vctip.exe -exec rm -f '{}' ';'

$ mkdir -p ".wine/drive_c/Program Files (x86)/Windows Kits"
$ cp -r "/mnt/Program Files (x86)/Windows Kits/10" \
  ".wine/drive_c/Program Files (x86)/Windows Kits/"

Add lower-case symlinks for upper-case named headers:

$ etc/lowercase-headers \
  ".wine/drive_c/Program Files (x86)/Windows Kits/10/Include"

Installing via the redistributable DLLs still does not work as of Wine 1.9.8.
Instead, we have to manually copy a bunch of DLLs from:

.wine/.../VC/Redist/MSVC/14.10.NNNNN/{x86 x64}/Microsoft.VC141.CRT/

And:

.wine/.../Windows Kits/10/Redist/ucrt/DLLs/{x86 x64}/

To:

.wine/drive_c/windows/{syswow64 system32}/

And add Wine overrides (run winecfg, select the "Libraries" tab, then enter
the DLL name and press "Add").

To discover the list of DLLs, run cl-15 to compile and link an executable and
then run the executable itself (see Test below): any DLL that causes an error
needs an override.

For Wine 1.7.55-1.9.8 the list is:

  api-ms-win-crt-runtime-l1-1-0.dll
  api-ms-win-crt-locale-l1-1-0.dll
  api-ms-win-crt-heap-l1-1-0.dll
  api-ms-win-crt-stdio-l1-1-0.dll
  api-ms-win-crt-conio-l1-1-0.dll
  ucrtbase.dll
  vcruntime140.dll
  msvcp140.dll

The following overrides are necessary because of some unimplemented functions:

  api-ms-win-crt-string-l1-1-0.dll
  api-ms-win-crt-time-l1-1-0.dll
  api-ms-win-crt-convert-l1-1-0.dll
  api-ms-win-core-rtlsupport-l1-1-0.dll

Note also that if you plan to run tests built against the debug runtime, then
also copy ucrtbased.dll, vcruntime140d.dll, and msvcp140d.dll from Windows
Kits/10/bin/.../ucrt/ and VC/Redist/.../debug_noredist/.


Copy and Setup Visual Studio 16
-------------------------------

The setup for 16 is similar to that of 15. Follow instructions in "Copy and
Setup Visual Studio 15", replacing year 2017 and version 15 with 2019 and 16,
respectively.

Regarding the redistributable DLLs, note that for Wine 4.0 (Staging) only the
following overrides appear to be necessary:

  vcruntime140.dll
  msvcp140.dll

Also note that linking for 32-bit builds may fail (see msvc-16/msvc-16.0-32
for details).


Test
----

cl-<...> /EHsc /MD /TP hello-world.cxx
./hello-world.exe


Usage
=====

To suppress Wine debug messages (especially advisable if running executables
built with more recent Visual Studio versions) you may want to add the
following line to your .bashrc or similar:

export WINEDEBUG=fixme-all


Hacking
=======

To add support for a new Visual Studio version follow this overall plan:


Install Visual Studio
---------------------

Install the new version on a Windows machine keeping the setup as close to
default as possible. Specifically, don't alter the default installation
directory, SDK to use, etc. Normally, you would make sure all the compilers
that you will need are installed (32, 64-bit x86, ARM, etc) and that's it.
Note also that we use the 64-to-32-bit cross-compiler for 32-bit builds.


Come up with Configuration(s)
-----------------------------

By examining the INCLUDE, IFCPATH and LIB environment variables in the
corresponding Visual Studio Command Prompts, determine which SDK/CRT versions
are used, executable paths for the tools (use the where command), etc.

Based on this information create the corresponding configuration file(s) in
msvc-NN/ subdirectory. Use the existing configuration from the closest version
as a guide.


Create Driver Scripts
---------------------

Create the driver scripts corresponding to each new configuration. For example
(replace <version> and <target>):

for t in cl link lib mt rc; do \
  cp cl-11-32 $t-<version>-<target>; done


Copy and Setup Visual Studio on Linux
-------------------------------------

Copy the Visual Studio setup over to a Linux machine as discussed above using
instructions from the closest version as a guide. Use the new driver scripts
for testing.

Write down new instructions or update one of the existing.


Update Common Scripts
---------------------

In a new version of Visual Studio the tools may have new options that may need
to be handled in the msvc-common/msvc-<tool>-common scripts. To check if any
were added, take a diff of usage outputs (/? option) from the new version and
the most recent that is already supported.