Skip to content

Commit 949ec2a

Browse files
committed
[Clang] [Driver] add a Cygwin ToolChain
Add a new Cygwin toolchain that just goes through the motions to initialize the Generic_GCC base properly. This allows removing some old, almost certainly wrong hard-coded paths from Lex/InitHeaderSearch.cpp Signed-off-by: Jeremy Drake <[email protected]>
1 parent 2667845 commit 949ec2a

File tree

6 files changed

+174
-83
lines changed

6 files changed

+174
-83
lines changed

Diff for: clang/lib/Driver/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ add_clang_library(clangDriver
5151
ToolChains/CrossWindows.cpp
5252
ToolChains/CSKYToolChain.cpp
5353
ToolChains/Cuda.cpp
54+
ToolChains/Cygwin.cpp
5455
ToolChains/Darwin.cpp
5556
ToolChains/DragonFly.cpp
5657
ToolChains/Flang.cpp

Diff for: clang/lib/Driver/Driver.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "ToolChains/Clang.h"
1818
#include "ToolChains/CrossWindows.h"
1919
#include "ToolChains/Cuda.h"
20+
#include "ToolChains/Cygwin.h"
2021
#include "ToolChains/Darwin.h"
2122
#include "ToolChains/DragonFly.h"
2223
#include "ToolChains/FreeBSD.h"
@@ -6849,6 +6850,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
68496850
case llvm::Triple::GNU:
68506851
TC = std::make_unique<toolchains::MinGW>(*this, Target, Args);
68516852
break;
6853+
case llvm::Triple::Cygnus:
6854+
TC = std::make_unique<toolchains::Cygwin>(*this, Target, Args);
6855+
break;
68526856
case llvm::Triple::Itanium:
68536857
TC = std::make_unique<toolchains::CrossWindowsToolChain>(*this, Target,
68546858
Args);

Diff for: clang/lib/Driver/ToolChains/Cygwin.cpp

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===--- Cygwin.cpp - Cygwin ToolChain Implementations ----------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "Cygwin.h"
10+
#include "CommonArgs.h"
11+
#include "clang/Config/config.h"
12+
#include "clang/Driver/Driver.h"
13+
#include "clang/Driver/Options.h"
14+
#include "llvm/Support/Path.h"
15+
#include "llvm/Support/VirtualFileSystem.h"
16+
17+
using namespace clang::driver;
18+
using namespace clang::driver::toolchains;
19+
using namespace clang;
20+
using namespace llvm::opt;
21+
22+
using tools::addPathIfExists;
23+
24+
Cygwin::Cygwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
25+
: Generic_GCC(D, Triple, Args) {
26+
GCCInstallation.init(Triple, Args);
27+
std::string SysRoot = computeSysRoot();
28+
ToolChain::path_list &PPaths = getProgramPaths();
29+
30+
Generic_GCC::PushPPaths(PPaths);
31+
32+
path_list &Paths = getFilePaths();
33+
34+
Generic_GCC::AddMultiarchPaths(D, SysRoot, "lib", Paths);
35+
36+
// Similar to the logic for GCC above, if we are currently running Clang
37+
// inside of the requested system root, add its parent library path to those
38+
// searched.
39+
// FIXME: It's not clear whether we should use the driver's installed
40+
// directory ('Dir' below) or the ResourceDir.
41+
if (StringRef(D.Dir).starts_with(SysRoot))
42+
addPathIfExists(D, D.Dir + "/../lib", Paths);
43+
44+
addPathIfExists(D, SysRoot + "/lib", Paths);
45+
addPathIfExists(D, SysRoot + "/usr/lib", Paths);
46+
addPathIfExists(D, SysRoot + "/usr/lib/w32api", Paths);
47+
}
48+
49+
llvm::ExceptionHandling Cygwin::GetExceptionModel(const ArgList &Args) const {
50+
if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64 ||
51+
getArch() == llvm::Triple::arm || getArch() == llvm::Triple::thumb)
52+
return llvm::ExceptionHandling::WinEH;
53+
return llvm::ExceptionHandling::DwarfCFI;
54+
}
55+
56+
void Cygwin::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
57+
ArgStringList &CC1Args) const {
58+
const Driver &D = getDriver();
59+
std::string SysRoot = computeSysRoot();
60+
61+
if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
62+
return;
63+
64+
if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
65+
addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
66+
67+
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
68+
SmallString<128> P(D.ResourceDir);
69+
llvm::sys::path::append(P, "include");
70+
addSystemInclude(DriverArgs, CC1Args, P);
71+
}
72+
73+
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
74+
return;
75+
76+
// Check for configure-time C include directories.
77+
StringRef CIncludeDirs(C_INCLUDE_DIRS);
78+
if (CIncludeDirs != "") {
79+
SmallVector<StringRef, 5> Dirs;
80+
CIncludeDirs.split(Dirs, ":");
81+
for (StringRef Dir : Dirs) {
82+
StringRef Prefix =
83+
llvm::sys::path::is_absolute(Dir) ? "" : StringRef(SysRoot);
84+
addExternCSystemInclude(DriverArgs, CC1Args, Prefix + Dir);
85+
}
86+
return;
87+
}
88+
89+
// Lacking those, try to detect the correct set of system includes for the
90+
// target triple.
91+
92+
AddMultilibIncludeArgs(DriverArgs, CC1Args);
93+
94+
// On systems using multiarch, add /usr/include/$triple before
95+
// /usr/include.
96+
std::string MultiarchIncludeDir = getTriple().str();
97+
if (!MultiarchIncludeDir.empty() &&
98+
D.getVFS().exists(SysRoot + "/usr/include/" + MultiarchIncludeDir))
99+
addExternCSystemInclude(DriverArgs, CC1Args,
100+
SysRoot + "/usr/include/" + MultiarchIncludeDir);
101+
102+
// Add an include of '/include' directly. This isn't provided by default by
103+
// system GCCs, but is often used with cross-compiling GCCs, and harmless to
104+
// add even when Clang is acting as-if it were a system compiler.
105+
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
106+
107+
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
108+
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/w32api");
109+
}

Diff for: clang/lib/Driver/ToolChains/Cygwin.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===--- Cygwin.h - Cygwin ToolChain Implementations ------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Cygwin_H
10+
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Cygwin_H
11+
12+
#include "Gnu.h"
13+
#include "clang/Driver/ToolChain.h"
14+
15+
namespace clang {
16+
namespace driver {
17+
namespace toolchains {
18+
19+
class LLVM_LIBRARY_VISIBILITY Cygwin : public Generic_GCC {
20+
public:
21+
Cygwin(const Driver &D, const llvm::Triple &Triple,
22+
const llvm::opt::ArgList &Args);
23+
24+
llvm::ExceptionHandling
25+
GetExceptionModel(const llvm::opt::ArgList &Args) const override;
26+
27+
void
28+
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
29+
llvm::opt::ArgStringList &CC1Args) const override;
30+
};
31+
32+
} // end namespace toolchains
33+
} // end namespace driver
34+
} // end namespace clang
35+
36+
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Cygwin_H

Diff for: clang/lib/Driver/ToolChains/Gnu.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,27 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
26322632
return;
26332633
}
26342634

2635+
if (TargetTriple.isWindowsCygwinEnvironment()) {
2636+
static const char *const CygwinX86Triples[] = {"i686-pc-cygwin",
2637+
"i686-pc-msys"};
2638+
static const char *const CygwinX86_64Triples[] = {"x86_64-pc-cygwin",
2639+
"x86_64-pc-msys"};
2640+
LibDirs.push_back("/lib");
2641+
switch (TargetTriple.getArch()) {
2642+
case llvm::Triple::x86_64:
2643+
TripleAliases.append(begin(CygwinX86_64Triples),
2644+
end(CygwinX86_64Triples));
2645+
break;
2646+
case llvm::Triple::x86:
2647+
TripleAliases.append(begin(CygwinX86Triples), end(CygwinX86Triples));
2648+
break;
2649+
default:
2650+
break;
2651+
}
2652+
2653+
return;
2654+
}
2655+
26352656
switch (TargetTriple.getArch()) {
26362657
case llvm::Triple::aarch64:
26372658
LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs));

Diff for: clang/lib/Lex/InitHeaderSearch.cpp

+3-83
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,10 @@ class InitHeaderSearch {
7474
SystemHeaderPrefixes.emplace_back(std::string(Prefix), IsSystemHeader);
7575
}
7676

77-
/// Add the necessary paths to support a MinGW libstdc++.
78-
void AddMinGWCPlusPlusIncludePaths(StringRef Base,
79-
StringRef Arch,
80-
StringRef Version);
81-
8277
/// Add paths that should always be searched.
8378
void AddDefaultCIncludePaths(const llvm::Triple &triple,
8479
const HeaderSearchOptions &HSOpts);
8580

86-
/// Add paths that should be searched when compiling c++.
87-
void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts,
88-
const llvm::Triple &triple,
89-
const HeaderSearchOptions &HSOpts);
90-
9181
/// Returns true iff AddDefaultIncludePaths should do anything. If this
9282
/// returns false, include paths should instead be handled in the driver.
9383
bool ShouldAddDefaultIncludePaths(const llvm::Triple &triple);
@@ -180,35 +170,14 @@ bool InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
180170
return false;
181171
}
182172

183-
void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
184-
StringRef Arch,
185-
StringRef Version) {
186-
AddPath(Base + "/" + Arch + "/" + Version + "/include/c++",
187-
CXXSystem, false);
188-
AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/" + Arch,
189-
CXXSystem, false);
190-
AddPath(Base + "/" + Arch + "/" + Version + "/include/c++/backward",
191-
CXXSystem, false);
192-
}
193-
194173
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
195174
const HeaderSearchOptions &HSOpts) {
196175
if (!ShouldAddDefaultIncludePaths(triple))
197176
llvm_unreachable("Include management is handled in the driver.");
198177

199-
llvm::Triple::OSType os = triple.getOS();
200-
201178
if (HSOpts.UseStandardSystemIncludes) {
202-
switch (os) {
203-
case llvm::Triple::Win32:
204-
if (triple.getEnvironment() != llvm::Triple::Cygnus)
205-
break;
206-
[[fallthrough]];
207-
default:
208-
// FIXME: temporary hack: hard-coded paths.
209-
AddPath("/usr/local/include", System, false);
210-
break;
211-
}
179+
// FIXME: temporary hack: hard-coded paths.
180+
AddPath("/usr/local/include", System, false);
212181
}
213182

214183
// Builtin includes use #include_next directives and should be positioned
@@ -236,51 +205,9 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
236205
return;
237206
}
238207

239-
switch (os) {
240-
case llvm::Triple::Win32:
241-
switch (triple.getEnvironment()) {
242-
default: llvm_unreachable("Include management is handled in the driver.");
243-
case llvm::Triple::Cygnus:
244-
AddPath("/usr/include/w32api", System, false);
245-
break;
246-
case llvm::Triple::GNU:
247-
break;
248-
}
249-
break;
250-
default:
251-
break;
252-
}
253-
254208
AddPath("/usr/include", ExternCSystem, false);
255209
}
256210

257-
void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
258-
const LangOptions &LangOpts, const llvm::Triple &triple,
259-
const HeaderSearchOptions &HSOpts) {
260-
if (!ShouldAddDefaultIncludePaths(triple))
261-
llvm_unreachable("Include management is handled in the driver.");
262-
263-
// FIXME: temporary hack: hard-coded paths.
264-
llvm::Triple::OSType os = triple.getOS();
265-
switch (os) {
266-
case llvm::Triple::Win32:
267-
switch (triple.getEnvironment()) {
268-
default: llvm_unreachable("Include management is handled in the driver.");
269-
case llvm::Triple::Cygnus:
270-
// Cygwin-1.7
271-
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3");
272-
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3");
273-
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
274-
// g++-4 / Cygwin-1.5
275-
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
276-
break;
277-
}
278-
break;
279-
default:
280-
break;
281-
}
282-
}
283-
284211
bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
285212
const llvm::Triple &triple) {
286213
switch (triple.getOS()) {
@@ -303,15 +230,10 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
303230
case llvm::Triple::Solaris:
304231
case llvm::Triple::UEFI:
305232
case llvm::Triple::WASI:
233+
case llvm::Triple::Win32:
306234
case llvm::Triple::ZOS:
307235
return false;
308236

309-
case llvm::Triple::Win32:
310-
if (triple.getEnvironment() != llvm::Triple::Cygnus ||
311-
triple.isOSBinFormatMachO())
312-
return false;
313-
break;
314-
315237
case llvm::Triple::UnknownOS:
316238
if (triple.isWasm() || triple.isAppleMachO())
317239
return false;
@@ -355,8 +277,6 @@ void InitHeaderSearch::AddDefaultIncludePaths(
355277
HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
356278
if (HSOpts.UseLibcxx) {
357279
AddPath("/usr/include/c++/v1", CXXSystem, false);
358-
} else {
359-
AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
360280
}
361281
}
362282

0 commit comments

Comments
 (0)