clang API Documentation
00001 //===--- ToolChains.cpp - ToolChain Implementations -----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "ToolChains.h" 00011 #include "clang/Basic/CharInfo.h" 00012 #include "clang/Basic/Version.h" 00013 #include "clang/Driver/Compilation.h" 00014 #include "clang/Driver/Driver.h" 00015 #include "clang/Driver/DriverDiagnostic.h" 00016 #include "clang/Driver/Options.h" 00017 #include "llvm/ADT/StringExtras.h" 00018 #include "llvm/Config/llvm-config.h" 00019 #include "llvm/Option/Arg.h" 00020 #include "llvm/Option/ArgList.h" 00021 #include "llvm/Support/ErrorHandling.h" 00022 #include "llvm/Support/FileSystem.h" 00023 #include "llvm/Support/Process.h" 00024 00025 // Include the necessary headers to interface with the Windows registry and 00026 // environment. 00027 #if defined(LLVM_ON_WIN32) 00028 #define USE_WIN32 00029 #endif 00030 00031 #ifdef USE_WIN32 00032 #define WIN32_LEAN_AND_MEAN 00033 #define NOGDI 00034 #define NOMINMAX 00035 #include <windows.h> 00036 #endif 00037 00038 using namespace clang::driver; 00039 using namespace clang::driver::toolchains; 00040 using namespace clang; 00041 using namespace llvm::opt; 00042 00043 MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple, 00044 const ArgList &Args) 00045 : ToolChain(D, Triple, Args) { 00046 } 00047 00048 Tool *MSVCToolChain::buildLinker() const { 00049 return new tools::visualstudio::Link(*this); 00050 } 00051 00052 Tool *MSVCToolChain::buildAssembler() const { 00053 if (getTriple().isOSBinFormatMachO()) 00054 return new tools::darwin::Assemble(*this); 00055 getDriver().Diag(clang::diag::err_no_external_assembler); 00056 return nullptr; 00057 } 00058 00059 bool MSVCToolChain::IsIntegratedAssemblerDefault() const { 00060 return true; 00061 } 00062 00063 bool MSVCToolChain::IsUnwindTablesDefault() const { 00064 // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms 00065 // such as ARM and PPC actually require unwind tables, but LLVM doesn't know 00066 // how to generate them yet. 00067 return getArch() == llvm::Triple::x86_64; 00068 } 00069 00070 bool MSVCToolChain::isPICDefault() const { 00071 return getArch() == llvm::Triple::x86_64; 00072 } 00073 00074 bool MSVCToolChain::isPIEDefault() const { 00075 return false; 00076 } 00077 00078 bool MSVCToolChain::isPICDefaultForced() const { 00079 return getArch() == llvm::Triple::x86_64; 00080 } 00081 00082 #ifdef USE_WIN32 00083 static bool readFullStringValue(HKEY hkey, const char *valueName, 00084 std::string &value) { 00085 // FIXME: We should be using the W versions of the registry functions, but 00086 // doing so requires UTF8 / UTF16 conversions similar to how we handle command 00087 // line arguments. The UTF8 conversion functions are not exposed publicly 00088 // from LLVM though, so in order to do this we will probably need to create 00089 // a registry abstraction in LLVMSupport that is Windows only. 00090 DWORD result = 0; 00091 DWORD valueSize = 0; 00092 DWORD type = 0; 00093 // First just query for the required size. 00094 result = RegQueryValueEx(hkey, valueName, NULL, &type, NULL, &valueSize); 00095 if (result != ERROR_SUCCESS || type != REG_SZ) 00096 return false; 00097 std::vector<BYTE> buffer(valueSize); 00098 result = RegQueryValueEx(hkey, valueName, NULL, NULL, &buffer[0], &valueSize); 00099 if (result == ERROR_SUCCESS) 00100 value.assign(reinterpret_cast<const char *>(buffer.data())); 00101 return result; 00102 } 00103 #endif 00104 00105 /// \brief Read registry string. 00106 /// This also supports a means to look for high-versioned keys by use 00107 /// of a $VERSION placeholder in the key path. 00108 /// $VERSION in the key path is a placeholder for the version number, 00109 /// causing the highest value path to be searched for and used. 00110 /// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION". 00111 /// There can be additional characters in the component. Only the numeric 00112 /// characters are compared. This function only searches HKLM. 00113 static bool getSystemRegistryString(const char *keyPath, const char *valueName, 00114 std::string &value, std::string *phValue) { 00115 #ifndef USE_WIN32 00116 return false; 00117 #else 00118 HKEY hRootKey = HKEY_LOCAL_MACHINE; 00119 HKEY hKey = NULL; 00120 long lResult; 00121 bool returnValue = false; 00122 00123 const char *placeHolder = strstr(keyPath, "$VERSION"); 00124 std::string bestName; 00125 // If we have a $VERSION placeholder, do the highest-version search. 00126 if (placeHolder) { 00127 const char *keyEnd = placeHolder - 1; 00128 const char *nextKey = placeHolder; 00129 // Find end of previous key. 00130 while ((keyEnd > keyPath) && (*keyEnd != '\\')) 00131 keyEnd--; 00132 // Find end of key containing $VERSION. 00133 while (*nextKey && (*nextKey != '\\')) 00134 nextKey++; 00135 size_t partialKeyLength = keyEnd - keyPath; 00136 char partialKey[256]; 00137 if (partialKeyLength > sizeof(partialKey)) 00138 partialKeyLength = sizeof(partialKey); 00139 strncpy(partialKey, keyPath, partialKeyLength); 00140 partialKey[partialKeyLength] = '\0'; 00141 HKEY hTopKey = NULL; 00142 lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY, 00143 &hTopKey); 00144 if (lResult == ERROR_SUCCESS) { 00145 char keyName[256]; 00146 double bestValue = 0.0; 00147 DWORD index, size = sizeof(keyName) - 1; 00148 for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL, 00149 NULL, NULL, NULL) == ERROR_SUCCESS; index++) { 00150 const char *sp = keyName; 00151 while (*sp && !isDigit(*sp)) 00152 sp++; 00153 if (!*sp) 00154 continue; 00155 const char *ep = sp + 1; 00156 while (*ep && (isDigit(*ep) || (*ep == '.'))) 00157 ep++; 00158 char numBuf[32]; 00159 strncpy(numBuf, sp, sizeof(numBuf) - 1); 00160 numBuf[sizeof(numBuf) - 1] = '\0'; 00161 double dvalue = strtod(numBuf, NULL); 00162 if (dvalue > bestValue) { 00163 // Test that InstallDir is indeed there before keeping this index. 00164 // Open the chosen key path remainder. 00165 bestName = keyName; 00166 // Append rest of key. 00167 bestName.append(nextKey); 00168 lResult = RegOpenKeyEx(hTopKey, bestName.c_str(), 0, 00169 KEY_READ | KEY_WOW64_32KEY, &hKey); 00170 if (lResult == ERROR_SUCCESS) { 00171 lResult = readFullStringValue(hKey, valueName, value); 00172 if (lResult == ERROR_SUCCESS) { 00173 bestValue = dvalue; 00174 if (phValue) 00175 *phValue = bestName; 00176 returnValue = true; 00177 } 00178 RegCloseKey(hKey); 00179 } 00180 } 00181 size = sizeof(keyName) - 1; 00182 } 00183 RegCloseKey(hTopKey); 00184 } 00185 } else { 00186 lResult = 00187 RegOpenKeyEx(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); 00188 if (lResult == ERROR_SUCCESS) { 00189 lResult = readFullStringValue(hKey, valueName, value); 00190 if (lResult == ERROR_SUCCESS) 00191 returnValue = true; 00192 if (phValue) 00193 phValue->clear(); 00194 RegCloseKey(hKey); 00195 } 00196 } 00197 return returnValue; 00198 #endif // USE_WIN32 00199 } 00200 00201 /// \brief Get Windows SDK installation directory. 00202 bool MSVCToolChain::getWindowsSDKDir(std::string &path, int &major, 00203 int &minor) const { 00204 std::string sdkVersion; 00205 // Try the Windows registry. 00206 bool hasSDKDir = getSystemRegistryString( 00207 "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION", 00208 "InstallationFolder", path, &sdkVersion); 00209 if (!sdkVersion.empty()) 00210 ::sscanf(sdkVersion.c_str(), "v%d.%d", &major, &minor); 00211 return hasSDKDir && !path.empty(); 00212 } 00213 00214 // Gets the library path required to link against the Windows SDK. 00215 bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const { 00216 std::string sdkPath; 00217 int sdkMajor = 0; 00218 int sdkMinor = 0; 00219 00220 path.clear(); 00221 if (!getWindowsSDKDir(sdkPath, sdkMajor, sdkMinor)) 00222 return false; 00223 00224 llvm::SmallString<128> libPath(sdkPath); 00225 llvm::sys::path::append(libPath, "Lib"); 00226 if (sdkMajor <= 7) { 00227 switch (getArch()) { 00228 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder. 00229 case llvm::Triple::x86: 00230 break; 00231 case llvm::Triple::x86_64: 00232 llvm::sys::path::append(libPath, "x64"); 00233 break; 00234 case llvm::Triple::arm: 00235 // It is not necessary to link against Windows SDK 7.x when targeting ARM. 00236 return false; 00237 default: 00238 return false; 00239 } 00240 } else { 00241 // Windows SDK 8.x installs libraries in a folder whose names depend on the 00242 // version of the OS you're targeting. By default choose the newest, which 00243 // usually corresponds to the version of the OS you've installed the SDK on. 00244 const char *tests[] = {"winv6.3", "win8", "win7"}; 00245 bool found = false; 00246 for (const char *test : tests) { 00247 llvm::SmallString<128> testPath(libPath); 00248 llvm::sys::path::append(testPath, test); 00249 if (llvm::sys::fs::exists(testPath.c_str())) { 00250 libPath = testPath; 00251 found = true; 00252 break; 00253 } 00254 } 00255 00256 if (!found) 00257 return false; 00258 00259 llvm::sys::path::append(libPath, "um"); 00260 switch (getArch()) { 00261 case llvm::Triple::x86: 00262 llvm::sys::path::append(libPath, "x86"); 00263 break; 00264 case llvm::Triple::x86_64: 00265 llvm::sys::path::append(libPath, "x64"); 00266 break; 00267 case llvm::Triple::arm: 00268 llvm::sys::path::append(libPath, "arm"); 00269 break; 00270 default: 00271 return false; 00272 } 00273 } 00274 00275 path = libPath.str(); 00276 return true; 00277 } 00278 00279 // Get the location to use for Visual Studio binaries. The location priority 00280 // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on 00281 // system (as reported by the registry). 00282 bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath, 00283 std::string &path) const { 00284 path.clear(); 00285 00286 SmallString<128> BinDir; 00287 00288 // First check the environment variables that vsvars32.bat sets. 00289 llvm::Optional<std::string> VcInstallDir = 00290 llvm::sys::Process::GetEnv("VCINSTALLDIR"); 00291 if (VcInstallDir.hasValue()) { 00292 BinDir = VcInstallDir.getValue(); 00293 llvm::sys::path::append(BinDir, "bin"); 00294 } else { 00295 // Next walk the PATH, trying to find a cl.exe in the path. If we find one, 00296 // use that. However, make sure it's not clang's cl.exe. 00297 llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH"); 00298 if (OptPath.hasValue()) { 00299 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; 00300 SmallVector<StringRef, 8> PathSegments; 00301 llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr); 00302 00303 for (StringRef PathSegment : PathSegments) { 00304 if (PathSegment.empty()) 00305 continue; 00306 00307 SmallString<128> FilePath(PathSegment); 00308 llvm::sys::path::append(FilePath, "cl.exe"); 00309 if (llvm::sys::fs::can_execute(FilePath.c_str()) && 00310 !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) { 00311 // If we found it on the PATH, use it exactly as is with no 00312 // modifications. 00313 path = PathSegment; 00314 return true; 00315 } 00316 } 00317 } 00318 00319 std::string installDir; 00320 // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the 00321 // registry then we have no choice but to fail. 00322 if (!getVisualStudioInstallDir(installDir)) 00323 return false; 00324 00325 // Regardless of what binary we're ultimately trying to find, we make sure 00326 // that this is a Visual Studio directory by checking for cl.exe. We use 00327 // cl.exe instead of other binaries like link.exe because programs such as 00328 // GnuWin32 also have a utility called link.exe, so cl.exe is the least 00329 // ambiguous. 00330 BinDir = installDir; 00331 llvm::sys::path::append(BinDir, "VC", "bin"); 00332 SmallString<128> ClPath(BinDir); 00333 llvm::sys::path::append(ClPath, "cl.exe"); 00334 00335 if (!llvm::sys::fs::can_execute(ClPath.c_str())) 00336 return false; 00337 } 00338 00339 if (BinDir.empty()) 00340 return false; 00341 00342 switch (getArch()) { 00343 case llvm::Triple::x86: 00344 break; 00345 case llvm::Triple::x86_64: 00346 llvm::sys::path::append(BinDir, "amd64"); 00347 break; 00348 case llvm::Triple::arm: 00349 llvm::sys::path::append(BinDir, "arm"); 00350 break; 00351 default: 00352 // Whatever this is, Visual Studio doesn't have a toolchain for it. 00353 return false; 00354 } 00355 path = BinDir.str(); 00356 return true; 00357 } 00358 00359 // Get Visual Studio installation directory. 00360 bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const { 00361 // First check the environment variables that vsvars32.bat sets. 00362 const char *vcinstalldir = getenv("VCINSTALLDIR"); 00363 if (vcinstalldir) { 00364 path = vcinstalldir; 00365 path = path.substr(0, path.find("\\VC")); 00366 return true; 00367 } 00368 00369 std::string vsIDEInstallDir; 00370 std::string vsExpressIDEInstallDir; 00371 // Then try the windows registry. 00372 bool hasVCDir = 00373 getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION", 00374 "InstallDir", vsIDEInstallDir, nullptr); 00375 if (hasVCDir && !vsIDEInstallDir.empty()) { 00376 path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE")); 00377 return true; 00378 } 00379 00380 bool hasVCExpressDir = 00381 getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION", 00382 "InstallDir", vsExpressIDEInstallDir, nullptr); 00383 if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) { 00384 path = vsExpressIDEInstallDir.substr( 00385 0, vsIDEInstallDir.find("\\Common7\\IDE")); 00386 return true; 00387 } 00388 00389 // Try the environment. 00390 const char *vs120comntools = getenv("VS120COMNTOOLS"); 00391 const char *vs100comntools = getenv("VS100COMNTOOLS"); 00392 const char *vs90comntools = getenv("VS90COMNTOOLS"); 00393 const char *vs80comntools = getenv("VS80COMNTOOLS"); 00394 00395 const char *vscomntools = nullptr; 00396 00397 // Find any version we can 00398 if (vs120comntools) 00399 vscomntools = vs120comntools; 00400 else if (vs100comntools) 00401 vscomntools = vs100comntools; 00402 else if (vs90comntools) 00403 vscomntools = vs90comntools; 00404 else if (vs80comntools) 00405 vscomntools = vs80comntools; 00406 00407 if (vscomntools && *vscomntools) { 00408 const char *p = strstr(vscomntools, "\\Common7\\Tools"); 00409 path = p ? std::string(vscomntools, p) : vscomntools; 00410 return true; 00411 } 00412 return false; 00413 } 00414 00415 void MSVCToolChain::AddSystemIncludeWithSubfolder(const ArgList &DriverArgs, 00416 ArgStringList &CC1Args, 00417 const std::string &folder, 00418 const char *subfolder) const { 00419 llvm::SmallString<128> path(folder); 00420 llvm::sys::path::append(path, subfolder); 00421 addSystemInclude(DriverArgs, CC1Args, path.str()); 00422 } 00423 00424 void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 00425 ArgStringList &CC1Args) const { 00426 if (DriverArgs.hasArg(options::OPT_nostdinc)) 00427 return; 00428 00429 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 00430 SmallString<128> P(getDriver().ResourceDir); 00431 llvm::sys::path::append(P, "include"); 00432 addSystemInclude(DriverArgs, CC1Args, P.str()); 00433 } 00434 00435 if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 00436 return; 00437 00438 // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat. 00439 if (const char *cl_include_dir = getenv("INCLUDE")) { 00440 SmallVector<StringRef, 8> Dirs; 00441 StringRef(cl_include_dir) 00442 .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false); 00443 for (StringRef Dir : Dirs) 00444 addSystemInclude(DriverArgs, CC1Args, Dir); 00445 if (!Dirs.empty()) 00446 return; 00447 } 00448 00449 std::string VSDir; 00450 00451 // When built with access to the proper Windows APIs, try to actually find 00452 // the correct include paths first. 00453 if (getVisualStudioInstallDir(VSDir)) { 00454 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include"); 00455 00456 std::string WindowsSDKDir; 00457 int major, minor; 00458 if (getWindowsSDKDir(WindowsSDKDir, major, minor)) { 00459 if (major >= 8) { 00460 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 00461 "include\\shared"); 00462 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 00463 "include\\um"); 00464 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 00465 "include\\winrt"); 00466 } else { 00467 AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir, 00468 "include"); 00469 } 00470 } else { 00471 addSystemInclude(DriverArgs, CC1Args, VSDir); 00472 } 00473 return; 00474 } 00475 00476 // As a fallback, select default install paths. 00477 // FIXME: Don't guess drives and paths like this on Windows. 00478 const StringRef Paths[] = { 00479 "C:/Program Files/Microsoft Visual Studio 10.0/VC/include", 00480 "C:/Program Files/Microsoft Visual Studio 9.0/VC/include", 00481 "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include", 00482 "C:/Program Files/Microsoft Visual Studio 8/VC/include", 00483 "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include" 00484 }; 00485 addSystemIncludes(DriverArgs, CC1Args, Paths); 00486 } 00487 00488 void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 00489 ArgStringList &CC1Args) const { 00490 // FIXME: There should probably be logic here to find libc++ on Windows. 00491 }