1 //===-- MSVCPaths.h - MSVC path-parsing helpers -----------------*- 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_WINDOWSDRIVER_MSVCPATHS_H
10 #define LLVM_WINDOWSDRIVER_MSVCPATHS_H
11 
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/TargetParser/Triple.h"
15 #include <optional>
16 #include <string>
17 
18 namespace llvm {
19 
20 namespace vfs {
21 class FileSystem;
22 }
23 
24 enum class SubDirectoryType {
25   Bin,
26   Include,
27   Lib,
28 };
29 
30 enum class ToolsetLayout {
31   OlderVS,
32   VS2017OrNewer,
33   DevDivInternal,
34 };
35 
36 // Windows SDKs and VC Toolchains group their contents into subdirectories based
37 // on the target architecture. This function converts an llvm::Triple::ArchType
38 // to the corresponding subdirectory name.
39 const char *archToWindowsSDKArch(llvm::Triple::ArchType Arch);
40 
41 // Similar to the above function, but for Visual Studios before VS2017.
42 const char *archToLegacyVCArch(llvm::Triple::ArchType Arch);
43 
44 // Similar to the above function, but for DevDiv internal builds.
45 const char *archToDevDivInternalArch(llvm::Triple::ArchType Arch);
46 
47 bool appendArchToWindowsSDKLibPath(int SDKMajor, llvm::SmallString<128> LibPath,
48                                    llvm::Triple::ArchType Arch,
49                                    std::string &path);
50 
51 // Get the path to a specific subdirectory in the current toolchain for
52 // a given target architecture.
53 // VS2017 changed the VC toolchain layout, so this should be used instead
54 // of hardcoding paths.
55 std::string getSubDirectoryPath(SubDirectoryType Type, ToolsetLayout VSLayout,
56                                 const std::string &VCToolChainPath,
57                                 llvm::Triple::ArchType TargetArch,
58                                 llvm::StringRef SubdirParent = "");
59 
60 // Check if the Include path of a specified version of Visual Studio contains
61 // specific header files. If not, they are probably shipped with Universal CRT.
62 bool useUniversalCRT(ToolsetLayout VSLayout, const std::string &VCToolChainPath,
63                      llvm::Triple::ArchType TargetArch,
64                      llvm::vfs::FileSystem &VFS);
65 
66 /// Get Windows SDK installation directory.
67 bool getWindowsSDKDir(vfs::FileSystem &VFS,
68                       std::optional<llvm::StringRef> WinSdkDir,
69                       std::optional<llvm::StringRef> WinSdkVersion,
70                       std::optional<llvm::StringRef> WinSysRoot,
71                       std::string &Path, int &Major,
72                       std::string &WindowsSDKIncludeVersion,
73                       std::string &WindowsSDKLibVersion);
74 
75 bool getUniversalCRTSdkDir(vfs::FileSystem &VFS,
76                            std::optional<llvm::StringRef> WinSdkDir,
77                            std::optional<llvm::StringRef> WinSdkVersion,
78                            std::optional<llvm::StringRef> WinSysRoot,
79                            std::string &Path, std::string &UCRTVersion);
80 
81 // Check command line arguments to try and find a toolchain.
82 bool findVCToolChainViaCommandLine(
83     vfs::FileSystem &VFS, std::optional<llvm::StringRef> VCToolsDir,
84     std::optional<llvm::StringRef> VCToolsVersion,
85     std::optional<llvm::StringRef> WinSysRoot, std::string &Path,
86     ToolsetLayout &VSLayout);
87 
88 // Check various environment variables to try and find a toolchain.
89 bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path,
90                                    ToolsetLayout &VSLayout);
91 
92 // Query the Setup Config server for installs, then pick the newest version
93 // and find its default VC toolchain. If `VCToolsVersion` is specified, that
94 // version is preferred over the latest version.
95 //
96 // This is the preferred way to discover new Visual Studios, as they're no
97 // longer listed in the registry.
98 bool
99 findVCToolChainViaSetupConfig(vfs::FileSystem &VFS,
100                               std::optional<llvm::StringRef> VCToolsVersion,
101                               std::string &Path, ToolsetLayout &VSLayout);
102 
103 // Look in the registry for Visual Studio installs, and use that to get
104 // a toolchain path. VS2017 and newer don't get added to the registry.
105 // So if we find something here, we know that it's an older version.
106 bool findVCToolChainViaRegistry(std::string &Path, ToolsetLayout &VSLayout);
107 
108 } // namespace llvm
109 
110 #endif
111