This doesn't work for VS 2015, but 2017 and 2019. For VS 2015, I haven't
found a suitable env var, and I don't want to parse LIB and/or PATH to
guess the target architecture (LDC_VSDIR_FORCE can still be used).
This reduces the overhead for auto-detecting and setting up an MSVC
toolchain from a very rough 1 second to about 8 milliseconds on my box.
Enabling the auto-detection by default (and so preferring MSVC over the
'internal' toolchain if there's a Visual C++ installation) is now
possible, fixing issues like #3402.
The MSVC setup now consists of the bare minimum - prepending 3
directories to the LIB env var and 1-2 directories to PATH.
As alternative to clearing VSINSTALLDIR if run in a pre-set environment,
or as alternative to setting LDC_VSDIR to some non-existing dummy dir to
prefer auto-detection and setup of the MSVC toolchain over using the
internal toolchain.
As it's an important option for cross-linking to Posix. It doesn't just
affect linking, but external assembling is probably very exotic
(-no-integrated-as).
And use the wide API for pure is-env-variable-set checks too, as the
first call to a narrow env API function would lead to the C runtime
preparing and maintaining both narrow and wide environments.
Some LLVM libs were missing from the linker flags for current LLVM 5.0.
It was only during troubleshooting that I noticed the MSVC special case in
FindLLVM.cmake. Getting rid of it entirely made the issues disappear. I
checked llvm-config.exe, and it's returning appropriate switches for the
MS toolchain, no need for special processing.
This apparently also leads to LLVM_CXXFLAGS being used for the first time
when building with MSVC. These include /W4, a level further up from
CMake's default /W3, so I disabled a few more frequent warnings.
I also had to link in a lib from Microsoft's Debug Info Access SDK
manually. As the VS command prompt unfortunately doesn't even include the
DIA SDK dir in the LIBPATH environment variable, I even had to specify a
full path, relying on the `VSINSTALLDIR` environment variable.
And merge the two out-of-sync copies for adding gcc target flags. The flag
was omitted for gcc as linker already, but not for gcc as external assembler.
Results in a 7.5% bigger RelWithDebInfo ldc2.exe on Win64 with LLVM 3.9.1.
LLD is currently enforced when building with LDC_WITH_LLD=ON. And LLD
still doesn't support debuginfo (.pdb) generation for MSVC targets.
For invoking MS tools such as link.exe and lib.exe, which require
compatible PATH, LIB, LIBPATH etc.
We previously wrapped the invokation of the tool with a batch file taking
care of setting up the environment and then calling the actual tool.
I changed this to first invoke another batch file setting up its
environment and then dumping all environment variables to a file. LDC then
parses this file and updates its own environment variables. Later spawned
child processes then inherit the updated environment, and the tools will
be located by LLVM in updated PATH.
This allows LDC to keep track of the used Visual C++ installation (and
could so set up additional runtime libs required since VS 2015, something
we would have needed some time back when we still supported VS 2013). It's
also required as a prerequisite for integrating LLD as in-process linker
on Windows.
I quickly looked into the option of setting up the environment manually,
but the MS batch files are full of quirks, mixtures of registry and
file-system lookups, checking for existence of misc. headers to filter out
bogus installations etc. With VS 2017, there's nothing in the registry at
all anymore (at least for the Build Tools); MS expose a COM interface for
querying the VS installer... But at least they still provide the batch
files.