Skip to content

Commit c6053a4

Browse files
authored
Merge pull request #2886 from kinke/mingw-w64
Windows: Make LDC package fully self-sufficient (get rid of MSVC dependency)
2 parents 9ebf72d + ef04326 commit c6053a4

File tree

7 files changed

+86
-25
lines changed

7 files changed

+86
-25
lines changed

appveyor.yml

+19-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ install:
8787
#echo 'Using LLVM with enabled assertions'
8888
#$assertsSuffix = '-withAsserts'
8989
}
90-
appveyor DownloadFile "https://github.com/ldc-developers/llvm/releases/download/ldc-v$Env:LLVM_VERSION/llvm-$Env:LLVM_VERSION-windows-$Env:APPVEYOR_JOB_ARCH$assertsSuffix.7z" -FileName llvm.7z
90+
appveyor DownloadFile "https://github.com/ldc-developers/llvm/releases/download/ldc-v$Env:LLVM_VERSION/llvm-$Env:LLVM_VERSION-windows-$Env:APPVEYOR_JOB_ARCH$assertsSuffix-clang.7z" -FileName llvm.7z
9191
- md llvm
9292
- cd llvm
9393
- 7z x ..\llvm.7z > nul
@@ -98,6 +98,8 @@ install:
9898
- set PATH=%CD%\llvm\bin;%CD%\ninja;%CD%\make;C:\Program Files\Git\usr\bin;%PATH%
9999
- if "%APPVEYOR_BUILD_WORKER_IMAGE:~-4%" == "2017" call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=%APPVEYOR_JOB_ARCH%
100100
- if "%APPVEYOR_BUILD_WORKER_IMAGE:~-4%" == "2015" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %APPVEYOR_JOB_ARCH%
101+
# Let CMake configure 64-bit clang-cl for 32-bit code emission
102+
- if "%APPVEYOR_JOB_ARCH%" == "x86" ( set "CFLAGS=-m32" && set "CXXFLAGS=-m32" && set "ASMFLAGS=-m32" )
101103
# Print environment info
102104
- set
103105
- msbuild /version
@@ -113,13 +115,13 @@ build_script:
113115
# Build bootstrap LDC
114116
- md bootstrap
115117
- cd bootstrap
116-
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ROOT_DIR=c:/projects/llvm ..\ldc
118+
- cmake -G Ninja -DCMAKE_C_COMPILER:PATH=clang-cl.exe -DCMAKE_CXX_COMPILER:PATH=clang-cl.exe -DCMAKE_BUILD_TYPE=Release -DLLVM_ROOT_DIR=c:/projects/llvm ..\ldc
117119
- ninja -j2 all
118120
- cd ..
119121
# Build LDC and stdlib unittest runners
120122
- md ninja-ldc
121123
- cd ninja-ldc
122-
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Release %EXTRA_CMAKE_FLAGS% -DCMAKE_INSTALL_PREFIX=c:\projects\ldc2-%APPVEYOR_JOB_ARCH% -DINCLUDE_INSTALL_DIR=c:/projects/ldc2-%APPVEYOR_JOB_ARCH%/import -DLLVM_ROOT_DIR=c:/projects/llvm -DD_COMPILER=c:\projects\bootstrap\bin\ldmd2.exe ..\ldc
124+
- cmake -G Ninja -DCMAKE_C_COMPILER:PATH=clang-cl.exe -DCMAKE_CXX_COMPILER:PATH=clang-cl.exe -DCMAKE_BUILD_TYPE=Release %EXTRA_CMAKE_FLAGS% -DCMAKE_INSTALL_PREFIX=c:\projects\ldc2-%APPVEYOR_JOB_ARCH% -DINCLUDE_INSTALL_DIR=c:/projects/ldc2-%APPVEYOR_JOB_ARCH%/import -DLLVM_ROOT_DIR=c:/projects/llvm -DD_COMPILER=c:\projects\bootstrap\bin\ldmd2.exe ..\ldc
123125
- ninja -j2 all all-test-runners
124126

125127
#---------------------------------#
@@ -166,6 +168,20 @@ after_test:
166168
}
167169
# Now rename the installation dir to test portability.
168170
ren "$ldcInstallDir" ldc2-install
171+
# Include MinGW-w64-based libs
172+
- ps: |
173+
cd c:\projects
174+
$ldcInstallDir = 'c:\projects\ldc2-install'
175+
mkdir mingw-w64-libs
176+
cd mingw-w64-libs
177+
appveyor DownloadFile "https://github.com/ldc-developers/mingw-w64-libs/releases/download/v6.0.0-rc.1/mingw-w64-libs-v6.0.0-rc.1.7z" -FileName mingw-w64-libs.7z
178+
7z x mingw-w64-libs.7z > $null
179+
If ($Env:APPVEYOR_JOB_ARCH -eq 'x64') {
180+
cp -r lib64 "$ldcInstallDir\lib\mingw"
181+
} Else {
182+
cp -r lib32 "$ldcInstallDir\lib\mingw"
183+
}
184+
cd ..
169185
# Hello world integration test with LTO (x64 only)
170186
- ps: |
171187
If ($Env:APPVEYOR_JOB_ARCH -eq 'x64') {

driver/linker-msvc.cpp

+14-5
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ int linkObjToBinaryMSVC(llvm::StringRef outputPath,
8585
fatal();
8686
}
8787

88+
const bool useInternalToolchain = useInternalToolchainForMSVC();
89+
8890
#ifdef _WIN32
89-
windows::setupMsvcEnvironment();
91+
if (!useInternalToolchain)
92+
windows::setupMsvcEnvironment();
9093
#endif
9194

9295
// build arguments
@@ -172,12 +175,18 @@ int linkObjToBinaryMSVC(llvm::StringRef outputPath,
172175
}
173176

174177
// lib dirs
175-
for (const char *dir_c : ConfigFile::instance.libDirs()) {
178+
const auto &libDirs = ConfigFile::instance.libDirs();
179+
for (const char *dir_c : libDirs) {
176180
const llvm::StringRef dir(dir_c);
177181
if (!dir.empty())
178182
args.push_back(("/LIBPATH:" + dir).str());
179183
}
180184

185+
if (useInternalToolchain && !libDirs.empty()) {
186+
args.push_back(
187+
(llvm::Twine("/LIBPATH:") + *libDirs.begin() + "/mingw").str());
188+
}
189+
181190
// default libs
182191
for (const auto &name : defaultLibNames) {
183192
args.push_back(name + ".lib");
@@ -212,9 +221,9 @@ int linkObjToBinaryMSVC(llvm::StringRef outputPath,
212221
logstr << "\n"; // FIXME where's flush ?
213222

214223
#if LDC_WITH_LLD
215-
if (useInternalLLDForLinking()) {
216-
const auto fullArgs =
217-
getFullArgs("lld-link", args, global.params.verbose);
224+
if (useInternalLLDForLinking() ||
225+
(useInternalToolchain && opts::linker.empty() && !opts::isUsingLTO())) {
226+
const auto fullArgs = getFullArgs("lld-link", args, global.params.verbose);
218227

219228
#if LDC_LLVM_VER >= 600
220229
const bool success = lld::coff::link(fullArgs, /*CanExitEarly=*/false);

driver/linker.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,23 @@ bool linkAgainstSharedDefaultLibs() {
182182

183183
//////////////////////////////////////////////////////////////////////////////
184184

185+
bool useInternalToolchainForMSVC() {
186+
#ifndef _WIN32
187+
return true;
188+
#else
189+
return !getenv("VSINSTALLDIR") && !getenv("LDC_VSDIR");
190+
#endif
191+
}
192+
185193
llvm::StringRef getMscrtLibName() {
186194
llvm::StringRef name = mscrtlib;
187195
if (name.empty()) {
188-
// default to static release variant
189-
name = linkFullyStatic() != llvm::cl::BOU_FALSE ? "libcmt" : "msvcrt";
196+
if (useInternalToolchainForMSVC()) {
197+
name = "vcruntime140";
198+
} else {
199+
// default to static release variant
200+
name = linkFullyStatic() != llvm::cl::BOU_FALSE ? "libcmt" : "msvcrt";
201+
}
190202
}
191203
return name;
192204
}

driver/linker.h

+6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ llvm::cl::boolOrDefault linkFullyStatic();
3939
*/
4040
bool linkAgainstSharedDefaultLibs();
4141

42+
/**
43+
* Indicates whether the internal 'toolchain' (-link-internally and MinGW-w64
44+
* libs) is to be used for MSVC targets.
45+
*/
46+
bool useInternalToolchainForMSVC();
47+
4248
/**
4349
* Returns the name of the MS C runtime library to link with.
4450
*/

packaging/README.txt

+27-14
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,37 @@
1-
This is a prebuilt binary package for LDC, the LLVM-based D compiler.
1+
This is a standalone (DMD-style) binary package for LDC, the LLVM-based D
2+
compiler.
23

34
No installation is required, simply use the executables in the 'bin' subfolder.
4-
Just make sure you have a Microsoft Visual C++ 2015 or 2017 installation, either
5-
via Visual Studio or via the stand-alone Visual C++ Build Tools, both freely
6-
available from Microsoft. LDC relies on the MS linker (unless using
7-
'-link-internally') and on the MSVCRT + WinSDK libraries.
85

96
The compiler configuration file is etc\ldc2.conf and can be easily customized
107
to your liking, e.g., adding implicit command-line options and setting up cross-
118
compilation.
129

13-
The LDC package is portable and should be able to detect your (latest) Visual
14-
C++ installation automatically.
15-
By setting the LDC_VSDIR environment variable to an existing Visual Studio
16-
directory, you can instruct LDC to use a specific Visual C++ installation.
17-
If run in a 'VS Native/Cross Tools Command Prompt' (i.e., if the environment
18-
variable VSINSTALLDIR is set), LDC skips the Visual C++ detection. This saves
19-
about one second for each linking operation, but linking will be restricted to
20-
the selected target (=> no cross-linking support via '-m32' in a x64 command
21-
prompt).
10+
The LDC package is portable and ships with LLD, the LLVM linker, as well as
11+
WinSDK & Visual C++ runtime (import) libraries based on MinGW-w64. In order to
12+
run the generated binaries, a Visual C++ 2015 runtime installation is required
13+
(vcruntime140.dll, ucrtbase.dll etc.).
14+
15+
In case you prefer an official Microsoft toolchain for linking (Visual C++ 2015
16+
or newer), e.g., to link with the static Microsoft libraries (and thus avoid the
17+
dependency on the Visual C++ runtime installation for your users), you have the
18+
following options:
19+
20+
* Run LDC in a 'VS Native/Cross Tools Command Prompt' (LDC checks whether the
21+
VSINSTALLDIR environment variable is set).
22+
LDC assumes the environment variables are all set up appropriately.
23+
* Set the LDC_VSDIR environment variable to some Visual Studio/Visual C++ Build
24+
Tools installation directory, e.g.,
25+
'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community'.
26+
LDC will invoke a batch file provided by VS to set up the environment
27+
variables for the selected 32/64-bit target platform, which adds an overhead
28+
of about 1 second for each linking operation.
29+
You can also set LDC_VSDIR to some non-existing dummy path; LDC will try to
30+
auto-detect your latest Visual C++ installation in that case.
31+
* Set up the etc\ldc2.conf config file and specify the path to the linker
32+
('-linker=<path>', or use '-link-internally') as well as the directories
33+
containing the MS libs ('-L/LIBPATH:<path1> -L/LIBPATH:<path2> ...'; check out
34+
the LIB environment variable in a VS tools command prompt).
2235

2336
For further information, including on how to report bugs, please refer to the
2437
LDC wiki: http://wiki.dlang.org/LDC.

runtime/druntime

tests/lit.site.cfg.in

+5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ env_cxx = os.environ.get('CXX', '')
6363
if env_cxx:
6464
config.environment['CXX'] = env_cxx
6565

66+
if (platform.system() == 'Windows'):
67+
config.environment['VSINSTALLDIR'] = os.environ['VSINSTALLDIR']
68+
config.environment['PATH'] = os.environ['PATH']
69+
config.environment['LIB'] = os.environ['LIB']
70+
6671
# Define available features so that we can disable tests depending on LLVM version
6772
config.available_features.add("llvm%d" % config.llvm_version)
6873
# LLVM version history: 3.9, 4.0, 5.0, ...

0 commit comments

Comments
 (0)