diff options
author | Michał Górny <mgorny@gentoo.org> | 2022-09-29 20:58:35 +0200 |
---|---|---|
committer | Michał Górny <mgorny@gentoo.org> | 2022-09-29 20:58:59 +0200 |
commit | 063e17d8b04b41cd8bd174aebb6603eb1a76d34a (patch) | |
tree | 1d36713e90bfe0fd64d67a2af49c83bebd215234 /clang/lib/Driver/Driver.cpp | |
parent | 062e515b701930a17e3d6b75b3a27cb4d9a6f984 (diff) | |
download | llvm-063e17d8b04b41cd8bd174aebb6603eb1a76d34a.zip llvm-063e17d8b04b41cd8bd174aebb6603eb1a76d34a.tar.gz llvm-063e17d8b04b41cd8bd174aebb6603eb1a76d34a.tar.bz2 |
[clang] [Driver] More flexible rules for loading default configs
Change the default config file loading logic to be more flexible
and more readable at the same time. The new algorithm focuses on four
locations, in order:
1. <triple>-<mode>.cfg using real driver mode
2. <triple>-<mode>.cfg using executable suffix
3. <triple>.cfg + <mode>.cfg using real driver mode
4. <triple>.cfg + <mode>.cfg using executable suffix
This is meant to preserve reasonable level of compatibility with
the existing use, while introducing more flexibility and making the code
simpler. Notably:
1. In this layout, the actual target triple is normally respected,
and e.g. in `-m32` build the `x86_64-*` configs will never be used.
2. Both real driver mode (preferable) and executable suffix are
supported. This permits correctly handling calls with explicit
`--driver-mode=` while at the same time preserving compatibility
with the existing code.
3. The first two locations provide users with the ability to override
configuration per specific target+mode combinaton, while the next two
make it possible to independently specify per-target and per-mode
configuration.
4. All config file locations are applicable independently of whether
clang is started via a prefixed executable, or bare `clang`.
5. If the target is not explicitly specified and the executable prefix
does not name a valid triple, it is used instead of the actual target
triple for backwards compatibility.
This is particularly meant to address Gentoo's use case for
configuration files: to configure the default runtimes (i.e. `-rtlib=`,
`-stdlib=`) and `--gcc-install-dir=` for all the relevant drivers,
as well as to make it more convenient for users to override `-W` flags
to test compatibility with future versions of Clang easier.
Differential Revision: https://reviews.llvm.org/D134337
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 140 |
1 files changed, 77 insertions, 63 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f2ae25d..b8ef379 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1068,79 +1068,74 @@ bool Driver::loadConfigFiles() { bool Driver::loadDefaultConfigFiles(ArrayRef<StringRef> CfgFileSearchDirs) { if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config)) return false; - if (ClangNameParts.TargetPrefix.empty()) - return false; - // If config file is not specified explicitly, try to deduce configuration - // from executable name. For instance, an executable 'armv7l-clang' will - // search for config file 'armv7l-clang.cfg'. - std::string CfgFileName = - ClangNameParts.TargetPrefix + '-' + ClangNameParts.ModeSuffix; - - // Determine architecture part of the file name, if it is present. - StringRef CfgFileArch = CfgFileName; - size_t ArchPrefixLen = CfgFileArch.find('-'); - if (ArchPrefixLen == StringRef::npos) - ArchPrefixLen = CfgFileArch.size(); - llvm::Triple CfgTriple; - CfgFileArch = CfgFileArch.take_front(ArchPrefixLen); - CfgTriple = llvm::Triple(llvm::Triple::normalize(CfgFileArch)); - if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch) - ArchPrefixLen = 0; - - if (!StringRef(CfgFileName).endswith(".cfg")) - CfgFileName += ".cfg"; - - // If config file starts with architecture name and command line options - // redefine architecture (with options like -m32 -LE etc), try finding new - // config file with that architecture. - SmallString<128> FixedConfigFile; - size_t FixedArchPrefixLen = 0; - if (ArchPrefixLen) { - // Get architecture name from config file name like 'i386.cfg' or - // 'armv7l-clang.cfg'. - // Check if command line options changes effective triple. - llvm::Triple EffectiveTriple = - computeTargetTriple(*this, CfgTriple.getTriple(), *CLOptions); - if (CfgTriple.getArch() != EffectiveTriple.getArch()) { - FixedConfigFile = EffectiveTriple.getArchName(); - FixedArchPrefixLen = FixedConfigFile.size(); - // Append the rest of original file name so that file name transforms - // like: i386-clang.cfg -> x86_64-clang.cfg. - if (ArchPrefixLen < CfgFileName.size()) - FixedConfigFile += CfgFileName.substr(ArchPrefixLen); - } - } - - // Try to find config file. First try file with corrected architecture. + std::string RealMode = getExecutableForDriverMode(Mode); + std::string Triple; + + // If name prefix is present, no --target= override was passed via CLOptions + // and the name prefix is not a valid triple, force it for backwards + // compatibility. + if (!ClangNameParts.TargetPrefix.empty() && + computeTargetTriple(*this, "/invalid/", *CLOptions).str() == + "/invalid/") { + llvm::Triple PrefixTriple{ClangNameParts.TargetPrefix}; + if (PrefixTriple.getArch() == llvm::Triple::UnknownArch || + PrefixTriple.isOSUnknown()) + Triple = PrefixTriple.str(); + } + + // Otherwise, use the real triple as used by the driver. + if (Triple.empty()) { + llvm::Triple RealTriple = + computeTargetTriple(*this, TargetTriple, *CLOptions); + Triple = RealTriple.str(); + assert(!Triple.empty()); + } + + // Search for config files in the following order: + // 1. <triple>-<mode>.cfg using real driver mode + // (e.g. i386-pc-linux-gnu-clang++.cfg). + // 2. <triple>-<mode>.cfg using executable suffix + // (e.g. i386-pc-linux-gnu-clang-g++.cfg for *clang-g++). + // 3. <triple>.cfg + <mode>.cfg using real driver mode + // (e.g. i386-pc-linux-gnu.cfg + clang++.cfg). + // 4. <triple>.cfg + <mode>.cfg using executable suffix + // (e.g. i386-pc-linux-gnu.cfg + clang-g++.cfg for *clang-g++). + + // Try loading <triple>-<mode>.cfg, and return if we find a match. llvm::SmallString<128> CfgFilePath; - if (!FixedConfigFile.empty()) { - if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile, - getVFS())) - return readConfigFile(CfgFilePath); - // If 'x86_64-clang.cfg' was not found, try 'x86_64.cfg'. - FixedConfigFile.resize(FixedArchPrefixLen); - FixedConfigFile.append(".cfg"); - if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile, - getVFS())) - return readConfigFile(CfgFilePath); - } - - // Then try original file name. + std::string CfgFileName = Triple + '-' + RealMode + ".cfg"; if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS())) return readConfigFile(CfgFilePath); - // Finally try removing driver mode part: 'x86_64-clang.cfg' -> 'x86_64.cfg'. - if (!ClangNameParts.ModeSuffix.empty() && - !ClangNameParts.TargetPrefix.empty()) { - CfgFileName.assign(ClangNameParts.TargetPrefix); - CfgFileName.append(".cfg"); + bool TryModeSuffix = !ClangNameParts.ModeSuffix.empty() && + ClangNameParts.ModeSuffix != RealMode; + if (TryModeSuffix) { + CfgFileName = Triple + '-' + ClangNameParts.ModeSuffix + ".cfg"; if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS())) return readConfigFile(CfgFilePath); } + // Try loading <mode>.cfg, and return if loading failed. If a matching file + // was not found, still proceed on to try <triple>.cfg. + CfgFileName = RealMode + ".cfg"; + if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS())) { + if (readConfigFile(CfgFilePath)) + return true; + } else if (TryModeSuffix) { + CfgFileName = ClangNameParts.ModeSuffix + ".cfg"; + if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()) && + readConfigFile(CfgFilePath)) + return true; + } + + // Try loading <triple>.cfg and return if we find a match. + CfgFileName = Triple + ".cfg"; + if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS())) + return readConfigFile(CfgFilePath); + // If we were unable to find a config file deduced from executable name, - // do not report an error. + // that is not an error. return false; } @@ -6201,6 +6196,25 @@ Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const { return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask); } +const char *Driver::getExecutableForDriverMode(DriverMode Mode) { + switch (Mode) { + case GCCMode: + return "clang"; + case GXXMode: + return "clang++"; + case CPPMode: + return "clang-cpp"; + case CLMode: + return "clang-cl"; + case FlangMode: + return "flang"; + case DXCMode: + return "clang-dxc"; + } + + llvm_unreachable("Unhandled Mode"); +} + bool clang::driver::isOptimizationLevelFast(const ArgList &Args) { return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false); } |