brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.5 KiB · 5300c5c Raw
775 lines · cpp
1//===-- llvm-config.cpp - LLVM project configuration utility --------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This tool encapsulates information about an LLVM project configuration for10// use by other project's build environments (to determine installed path,11// available features, required libraries, etc.).12//13// Note that although this tool *may* be used by some parts of LLVM's build14// itself (i.e., the Makefiles use it to compute required libraries when linking15// tools), this tool is primarily designed to support external projects.16//17//===----------------------------------------------------------------------===//18 19#include "llvm/Config/llvm-config.h"20#include "llvm/ADT/STLExtras.h"21#include "llvm/ADT/StringMap.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/ADT/Twine.h"24#include "llvm/Config/config.h"25#include "llvm/Support/FileSystem.h"26#include "llvm/Support/Path.h"27#include "llvm/Support/Program.h"28#include "llvm/Support/WithColor.h"29#include "llvm/Support/raw_ostream.h"30#include "llvm/TargetParser/Triple.h"31#include <cstdlib>32#include <set>33#include <unordered_set>34#include <vector>35 36using namespace llvm;37 38// Include the build time variables we can report to the user. This is generated39// at build time from the BuildVariables.inc.in file by the build system.40#include "BuildVariables.inc"41 42// Include the component table. This creates an array of struct43// AvailableComponent entries, which record the component name, library name,44// and required components for all of the available libraries.45//46// Not all components define a library, we also use "library groups" as a way to47// create entries for pseudo groups like x86 or all-targets.48#include "LibraryDependencies.inc"49 50// Built-in extensions also register their dependencies, but in a separate file,51// later in the process.52#include "ExtensionDependencies.inc"53 54// LinkMode determines what libraries and flags are returned by llvm-config.55enum LinkMode {56  // LinkModeAuto will link with the default link mode for the installation,57  // which is dependent on the value of LLVM_LINK_LLVM_DYLIB, and fall back58  // to the alternative if the required libraries are not available.59  LinkModeAuto = 0,60 61  // LinkModeShared will link with the dynamic component libraries if they62  // exist, and return an error otherwise.63  LinkModeShared = 1,64 65  // LinkModeStatic will link with the static component libraries if they66  // exist, and return an error otherwise.67  LinkModeStatic = 2,68};69 70/// Traverse a single component adding to the topological ordering in71/// \arg RequiredLibs.72///73/// \param Name - The component to traverse.74/// \param ComponentMap - A prebuilt map of component names to descriptors.75/// \param VisitedComponents [in] [out] - The set of already visited components.76/// \param RequiredLibs [out] - The ordered list of required77/// libraries.78/// \param GetComponentNames - Get the component names instead of the79/// library name.80static void visitComponent(const std::string &Name,81                           const StringMap<AvailableComponent *> &ComponentMap,82                           std::set<AvailableComponent *> &VisitedComponents,83                           std::vector<std::string> &RequiredLibs,84                           bool IncludeNonInstalled, bool GetComponentNames,85                           const std::function<std::string(const StringRef &)>86                               *GetComponentLibraryPath,87                           std::vector<std::string> *Missing,88                           const std::string &DirSep) {89  // Lookup the component.90  AvailableComponent *AC = ComponentMap.lookup(Name);91  if (!AC) {92    errs() << "Can't find component: '" << Name << "' in the map. Available components are: ";93    for (const auto &Component : ComponentMap)94      errs() << "'" << Component.first() << "' ";95    errs() << "\n";96    report_fatal_error("abort");97  }98  assert(AC && "Invalid component name!");99 100  // Add to the visited table.101  if (!VisitedComponents.insert(AC).second) {102    // We are done if the component has already been visited.103    return;104  }105 106  // Only include non-installed components if requested.107  if (!AC->IsInstalled && !IncludeNonInstalled)108    return;109 110  // Otherwise, visit all the dependencies.111  for (const char *Lib : AC->RequiredLibraries) {112    if (!Lib)113      break;114    visitComponent(Lib, ComponentMap, VisitedComponents, RequiredLibs,115                   IncludeNonInstalled, GetComponentNames,116                   GetComponentLibraryPath, Missing, DirSep);117  }118 119  // Special handling for the special 'extensions' component. Its content is120  // not populated by llvm-build, but later in the process and loaded from121  // ExtensionDependencies.inc.122  if (Name == "extensions") {123    for (const ExtensionDescriptor &AvailableExtension : AvailableExtensions) {124      for (const char *Lib : AvailableExtension.RequiredLibraries) {125        if (!Lib)126          break;127        AvailableComponent *AC = ComponentMap.lookup(Lib);128        if (!AC)129          RequiredLibs.push_back(Lib);130        else131          visitComponent(Lib, ComponentMap, VisitedComponents, RequiredLibs,132                         IncludeNonInstalled, GetComponentNames,133                         GetComponentLibraryPath, Missing, DirSep);134      }135    }136  }137 138  if (GetComponentNames) {139    RequiredLibs.push_back(Name);140    return;141  }142 143  // Add to the required library list.144  if (AC->Library) {145    if (Missing && GetComponentLibraryPath) {146      std::string path = (*GetComponentLibraryPath)(AC->Library);147      if (DirSep == "\\")148        llvm::replace(path, '/', '\\');149      if (!sys::fs::exists(path))150        Missing->push_back(path);151    }152    RequiredLibs.push_back(AC->Library);153  }154}155 156/// Compute the list of required libraries for a given list of157/// components, in an order suitable for passing to a linker (that is, libraries158/// appear prior to their dependencies).159///160/// \param Components - The names of the components to find libraries for.161/// \param IncludeNonInstalled - Whether non-installed components should be162/// reported.163/// \param GetComponentNames - True if one would prefer the component names.164static std::vector<std::string>165computeLibsForComponents(ArrayRef<StringRef> Components,166                         bool IncludeNonInstalled, bool GetComponentNames,167                         const std::function<std::string(const StringRef &)>168                             *GetComponentLibraryPath,169                         std::vector<std::string> *Missing,170                         const std::string &DirSep) {171  std::vector<std::string> RequiredLibs;172  std::set<AvailableComponent *> VisitedComponents;173 174  // Build a map of component names to information.175  StringMap<AvailableComponent *> ComponentMap;176  for (auto &AC : AvailableComponents)177    ComponentMap[AC.Name] = &AC;178 179  // Visit the components.180  for (StringRef Component : Components) {181    // Users are allowed to provide mixed case component names.182    std::string ComponentLower = Component.lower();183 184    // Validate that the user supplied a valid component name.185    if (!ComponentMap.count(ComponentLower)) {186      errs() << "llvm-config: unknown component name: " << Component << "\n";187      exit(1);188    }189 190    visitComponent(ComponentLower, ComponentMap, VisitedComponents,191                   RequiredLibs, IncludeNonInstalled, GetComponentNames,192                   GetComponentLibraryPath, Missing, DirSep);193  }194 195  // The list is now ordered with leafs first, we want the libraries to printed196  // in the reverse order of dependency.197  std::reverse(RequiredLibs.begin(), RequiredLibs.end());198 199  return RequiredLibs;200}201 202static void usage(bool ExitWithFailure = true) {203  errs() << "\204usage: llvm-config <OPTION>... [<COMPONENT>...]\n\205\n\206Get various configuration information needed to compile programs which use\n\207LLVM.  Typically called from 'configure' scripts.  Examples:\n\208  llvm-config --cxxflags\n\209  llvm-config --ldflags\n\210  llvm-config --libs engine bcreader scalaropts\n\211\n\212Options:\n\213  --assertion-mode  Print assertion mode of LLVM tree (ON or OFF).\n\214  --bindir          Directory containing LLVM executables.\n\215  --build-mode      Print build mode of LLVM tree (e.g. Debug or Release).\n\216  --build-system    Print the build system used to build LLVM (e.g. `cmake` or `gn`).\n\217  --cflags          C compiler flags for files that include LLVM headers.\n\218  --cmakedir        Directory containing LLVM CMake modules.\n\219  --components      List of all possible components.\n\220  --cppflags        C preprocessor flags for files that include LLVM headers.\n\221  --cxxflags        C++ compiler flags for files that include LLVM headers.\n\222  --has-rtti        Print whether or not LLVM was built with rtti (YES or NO).\n\223  --help            Print a summary of llvm-config arguments.\n\224  --host-target     Target triple used to configure LLVM.\n\225  --ignore-libllvm  Ignore libLLVM and link component libraries instead.\n\226  --includedir      Directory containing LLVM headers.\n\227  --ldflags         Print Linker flags.\n\228  --libdir          Directory containing LLVM libraries.\n\229  --libfiles        Fully qualified library filenames for makefile depends.\n\230  --libnames        Bare library names for in-tree builds.\n\231  --libs            Libraries needed to link against LLVM components.\n\232  --link-shared     Link the components as shared libraries.\n\233  --link-static     Link the component libraries statically.\n\234  --obj-root        Print the object root used to build LLVM.\n\235  --prefix          Print the installation prefix.\n\236  --quote-paths     Quote and escape paths when needed.\n\237  --shared-mode     Print how the provided components can be collectively linked (`shared` or `static`).\n\238  --system-libs     System Libraries needed to link against LLVM components.\n\239  --targets-built   List of all targets currently built.\n\240  --version         Print LLVM version.\n\241Typical components:\n\242  all               All LLVM libraries (default).\n\243  engine            Either a native JIT or a bitcode interpreter.\n";244  if (ExitWithFailure)245    exit(1);246}247 248/// Compute the path to the main executable.249static std::string getExecutablePath(const char *Argv0) {250  // This just needs to be some symbol in the binary; C++ doesn't251  // allow taking the address of ::main however.252  void *P = (void *)(intptr_t)getExecutablePath;253  return sys::fs::getMainExecutable(Argv0, P);254}255 256/// Expand the semi-colon delimited LLVM_DYLIB_COMPONENTS into257/// the full list of components.258static std::vector<std::string>259getAllDyLibComponents(const bool IsInDevelopmentTree,260                      const bool GetComponentNames, const std::string &DirSep) {261  std::vector<StringRef> DyLibComponents;262 263  StringRef DyLibComponentsStr(LLVM_DYLIB_COMPONENTS);264  size_t Offset = 0;265  while (true) {266    const size_t NextOffset = DyLibComponentsStr.find(';', Offset);267    DyLibComponents.push_back(DyLibComponentsStr.substr(Offset, NextOffset-Offset));268    if (NextOffset == std::string::npos)269      break;270    Offset = NextOffset + 1;271  }272 273  assert(!DyLibComponents.empty());274 275  return computeLibsForComponents(DyLibComponents,276                                  /*IncludeNonInstalled=*/IsInDevelopmentTree,277                                  GetComponentNames, nullptr, nullptr, DirSep);278}279 280int main(int argc, char **argv) {281  std::vector<StringRef> Components;282  bool PrintLibs = false, PrintLibNames = false, PrintLibFiles = false;283  bool PrintSystemLibs = false, PrintSharedMode = false;284  bool HasAnyOption = false;285 286  // llvm-config is designed to support being run both from a development tree287  // and from an installed path. We try and auto-detect which case we are in so288  // that we can report the correct information when run from a development289  // tree.290  bool IsInDevelopmentTree;291  enum { CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout;292  SmallString<256> CurrentPath(getExecutablePath(argv[0]));293  std::string CurrentExecPrefix;294  std::string ActiveObjRoot;295 296  // If CMAKE_CFG_INTDIR is given, honor it as build mode.297  char const *build_mode = LLVM_BUILDMODE;298#if defined(CMAKE_CFG_INTDIR)299  if (!(CMAKE_CFG_INTDIR[0] == '.' && CMAKE_CFG_INTDIR[1] == '\0'))300    build_mode = CMAKE_CFG_INTDIR;301#endif302 303  // Create an absolute path, and pop up one directory (we expect to be inside a304  // bin dir).305  sys::fs::make_absolute(CurrentPath);306  CurrentExecPrefix =307      sys::path::parent_path(sys::path::parent_path(CurrentPath)).str();308 309  // Check to see if we are inside a development tree by comparing to possible310  // locations (prefix style or CMake style).311  if (sys::fs::equivalent(CurrentExecPrefix, LLVM_OBJ_ROOT)) {312    IsInDevelopmentTree = true;313    DevelopmentTreeLayout = CMakeStyle;314    ActiveObjRoot = LLVM_OBJ_ROOT;315  } else if (sys::fs::equivalent(sys::path::parent_path(CurrentExecPrefix),316                                 LLVM_OBJ_ROOT)) {317    IsInDevelopmentTree = true;318    DevelopmentTreeLayout = CMakeBuildModeStyle;319    ActiveObjRoot = LLVM_OBJ_ROOT;320  } else {321    IsInDevelopmentTree = false;322    DevelopmentTreeLayout = CMakeStyle; // Initialized to avoid warnings.323  }324 325  // Compute various directory locations based on the derived location326  // information.327  std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,328              ActiveCMakeDir;329  std::vector<std::string> ActiveIncludeOptions;330  if (IsInDevelopmentTree) {331    ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include";332    ActivePrefix = CurrentExecPrefix;333 334    // CMake organizes the products differently than a normal prefix style335    // layout.336    switch (DevelopmentTreeLayout) {337    case CMakeStyle:338      ActiveBinDir = ActiveObjRoot + "/bin";339      ActiveLibDir = ActiveObjRoot + "/lib" + LLVM_LIBDIR_SUFFIX;340      ActiveCMakeDir = ActiveLibDir + "/cmake/llvm";341      break;342    case CMakeBuildModeStyle:343      // FIXME: Should we consider the build-mode-specific path as the prefix?344      ActivePrefix = ActiveObjRoot;345      ActiveBinDir = ActiveObjRoot + "/" + build_mode + "/bin";346      ActiveLibDir =347          ActiveObjRoot + "/" + build_mode + "/lib" + LLVM_LIBDIR_SUFFIX;348      // The CMake directory isn't separated by build mode.349      ActiveCMakeDir =350          ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX + "/cmake/llvm";351      break;352    }353 354    // We need to include files from both the source and object trees.355    ActiveIncludeOptions.push_back(ActiveIncludeDir);356    ActiveIncludeOptions.push_back(ActiveObjRoot + "/include");357  } else {358    ActivePrefix = CurrentExecPrefix;359    {360      SmallString<256> Path(LLVM_INSTALL_INCLUDEDIR);361      sys::path::make_absolute(ActivePrefix, Path);362      ActiveIncludeDir = std::string(Path);363    }364    {365      SmallString<256> Path(LLVM_TOOLS_INSTALL_DIR);366      sys::path::make_absolute(ActivePrefix, Path);367      ActiveBinDir = std::string(Path);368    }369    ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX;370    {371      SmallString<256> Path(LLVM_INSTALL_PACKAGE_DIR);372      sys::path::make_absolute(ActivePrefix, Path);373      ActiveCMakeDir = std::string(Path);374    }375    ActiveIncludeOptions.push_back(ActiveIncludeDir);376  }377 378  /// We only use `shared library` mode in cases where the static library form379  /// of the components provided are not available; note however that this is380  /// skipped if we're run from within the build dir. However, once installed,381  /// we still need to provide correct output when the static archives are382  /// removed or, as in the case of CMake's `BUILD_SHARED_LIBS`, never present383  /// in the first place. This can't be done at configure/build time.384 385  StringRef SharedExt, SharedVersionedExt, SharedDir, SharedPrefix, StaticExt,386      StaticPrefix, StaticDir = "lib";387  std::string DirSep = "/";388  const Triple HostTriple(Triple::normalize(LLVM_HOST_TRIPLE));389  if (HostTriple.isOSWindows()) {390    SharedExt = "dll";391    SharedVersionedExt = LLVM_DYLIB_VERSION ".dll";392    if (HostTriple.isOSCygMing()) {393      SharedPrefix = LLVM_SHARED_LIBRARY_PREFIX;394      StaticExt = "a";395      StaticPrefix = "lib";396    } else {397      StaticExt = "lib";398      DirSep = "\\";399      llvm::replace(ActiveObjRoot, '/', '\\');400      llvm::replace(ActivePrefix, '/', '\\');401      llvm::replace(ActiveBinDir, '/', '\\');402      llvm::replace(ActiveLibDir, '/', '\\');403      llvm::replace(ActiveCMakeDir, '/', '\\');404      llvm::replace(ActiveIncludeDir, '/', '\\');405      for (auto &Include : ActiveIncludeOptions)406        llvm::replace(Include, '/', '\\');407    }408    SharedDir = ActiveBinDir;409    StaticDir = ActiveLibDir;410  } else if (HostTriple.isOSDarwin()) {411    SharedExt = "dylib";412    SharedVersionedExt = LLVM_DYLIB_VERSION ".dylib";413    StaticExt = "a";414    StaticDir = SharedDir = ActiveLibDir;415    StaticPrefix = SharedPrefix = "lib";416  } else {417    // default to the unix values:418    SharedExt = "so";419    SharedVersionedExt = LLVM_DYLIB_VERSION ".so";420    StaticExt = "a";421    StaticDir = SharedDir = ActiveLibDir;422    StaticPrefix = SharedPrefix = "lib";423  }424 425  const bool BuiltDyLib = !!LLVM_ENABLE_DYLIB;426 427  /// CMake style shared libs, ie each component is in a shared library.428  const bool BuiltSharedLibs = !!LLVM_ENABLE_SHARED;429 430  bool DyLibExists = false;431  const std::string DyLibName =432      (SharedPrefix + "LLVM-" + SharedVersionedExt).str();433 434  // If LLVM_LINK_DYLIB is ON, the single shared library will be returned435  // for "--libs", etc, if they exist. This behaviour can be overridden with436  // --link-static or --link-shared.437  bool LinkDyLib = !!LLVM_LINK_DYLIB;438 439  if (BuiltDyLib) {440    std::string path((SharedDir + DirSep + DyLibName).str());441    if (DirSep == "\\")442      llvm::replace(path, '/', '\\');443    DyLibExists = sys::fs::exists(path);444    if (!DyLibExists) {445      // The shared library does not exist: don't error unless the user446      // explicitly passes --link-shared.447      LinkDyLib = false;448    }449  }450  LinkMode LinkMode =451      (LinkDyLib || BuiltSharedLibs) ? LinkModeShared : LinkModeAuto;452 453  /// Get the component's library name without the lib prefix and the454  /// extension. Returns true if Lib is in a recognized format.455  auto GetComponentLibraryNameSlice = [&](const StringRef &Lib,456                                          StringRef &Out) {457    if (Lib.starts_with(StaticPrefix) || Lib.starts_with(SharedPrefix)) {458      unsigned FromEnd;459      if (Lib.ends_with(StaticExt))460        FromEnd = StaticExt.size() + 1;461      else if (Lib.ends_with(SharedExt))462        FromEnd = SharedExt.size() + 1;463      else464        FromEnd = 0;465 466      if (FromEnd != 0) {467        unsigned FromStart = Lib.starts_with(SharedPrefix)468                                 ? SharedPrefix.size()469                                 : StaticPrefix.size();470        Out = Lib.slice(FromStart, Lib.size() - FromEnd);471        return true;472      }473    }474 475    return false;476  };477  /// Maps Unixizms to the host platform.478  auto GetComponentLibraryFileName = [&](const StringRef &Lib,479                                         const bool Shared) {480    std::string LibFileName;481    if (Shared) {482      if (Lib == DyLibName) {483        // Treat the DyLibName specially. It is not a component library and484        // already has the necessary prefix and suffix (e.g. `.so`) added so485        // just return it unmodified.486        assert(Lib.ends_with(SharedExt) && "DyLib is missing suffix");487        LibFileName = std::string(Lib);488      } else {489        LibFileName = (SharedPrefix + Lib + "." + SharedExt).str();490      }491    } else {492      // default to static493      LibFileName = (StaticPrefix + Lib + "." + StaticExt).str();494    }495 496    return LibFileName;497  };498  /// Get the full path for a possibly shared component library.499  auto GetComponentLibraryPath = [&](const StringRef &Name, const bool Shared) {500    auto LibFileName = GetComponentLibraryFileName(Name, Shared);501    if (Shared)502      return (SharedDir + DirSep + LibFileName).str();503    else504      return (StaticDir + DirSep + LibFileName).str();505  };506 507  raw_ostream &OS = outs();508 509  // Check if we want quoting and escaping.510  bool QuotePaths = std::any_of(&argv[0], &argv[argc], [](const char *Arg) {511    return StringRef(Arg) == "--quote-paths";512  });513 514  auto MaybePrintQuoted = [&](StringRef Str) {515    if (QuotePaths)516      sys::printArg(OS, Str, /*Quote=*/false); // only add quotes if necessary517    else518      OS << Str;519  };520 521  // Render include paths and associated flags522  auto RenderFlags = [&](StringRef Flags) {523    bool First = true;524    for (auto &Include : ActiveIncludeOptions) {525      if (!First)526        OS << ' ';527      std::string FlagsStr = "-I" + Include;528      MaybePrintQuoted(FlagsStr);529      First = false;530    }531    OS << ' ' << Flags << '\n';532  };533 534  for (int i = 1; i != argc; ++i) {535    StringRef Arg = argv[i];536 537    if (Arg.starts_with("-")) {538      HasAnyOption = true;539      if (Arg == "--version") {540        OS << PACKAGE_VERSION << '\n';541      } else if (Arg == "--prefix") {542        MaybePrintQuoted(ActivePrefix);543        OS << '\n';544      } else if (Arg == "--bindir") {545        MaybePrintQuoted(ActiveBinDir);546        OS << '\n';547      } else if (Arg == "--includedir") {548        MaybePrintQuoted(ActiveIncludeDir);549        OS << '\n';550      } else if (Arg == "--libdir") {551        MaybePrintQuoted(ActiveLibDir);552        OS << '\n';553      } else if (Arg == "--cmakedir") {554        MaybePrintQuoted(ActiveCMakeDir);555        OS << '\n';556      } else if (Arg == "--cppflags") {557        RenderFlags(LLVM_CPPFLAGS);558      } else if (Arg == "--cflags") {559        RenderFlags(LLVM_CFLAGS);560      } else if (Arg == "--cxxflags") {561        RenderFlags(LLVM_CXXFLAGS);562      } else if (Arg == "--ldflags") {563        std::string LDFlags =564            HostTriple.isWindowsMSVCEnvironment() ? "-LIBPATH:" : "-L";565        LDFlags += ActiveLibDir;566        MaybePrintQuoted(LDFlags);567        OS << ' ' << LLVM_LDFLAGS << '\n';568      } else if (Arg == "--system-libs") {569        PrintSystemLibs = true;570      } else if (Arg == "--libs") {571        PrintLibs = true;572      } else if (Arg == "--libnames") {573        PrintLibNames = true;574      } else if (Arg == "--libfiles") {575        PrintLibFiles = true;576      } else if (Arg == "--components") {577        /// If there are missing static archives and a dylib was578        /// built, print LLVM_DYLIB_COMPONENTS instead of everything579        /// in the manifest.580        std::vector<std::string> Components;581        for (const auto &AC : AvailableComponents) {582          // Only include non-installed components when in a development tree.583          if (!AC.IsInstalled && !IsInDevelopmentTree)584            continue;585 586          Components.push_back(AC.Name);587          if (AC.Library && !IsInDevelopmentTree) {588            std::string path(GetComponentLibraryPath(AC.Library, false));589            if (DirSep == "\\")590              llvm::replace(path, '/', '\\');591            if (DyLibExists && !sys::fs::exists(path)) {592              Components =593                  getAllDyLibComponents(IsInDevelopmentTree, true, DirSep);594              llvm::sort(Components);595              break;596            }597          }598        }599 600        interleave(Components, OS, " ");601        OS << '\n';602      } else if (Arg == "--targets-built") {603        OS << LLVM_TARGETS_BUILT << '\n';604      } else if (Arg == "--host-target") {605        OS << Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE) << '\n';606      } else if (Arg == "--build-mode") {607        OS << build_mode << '\n';608      } else if (Arg == "--assertion-mode") {609#if defined(NDEBUG)610        OS << "OFF\n";611#else612        OS << "ON\n";613#endif614      } else if (Arg == "--build-system") {615        OS << LLVM_BUILD_SYSTEM << '\n';616      } else if (Arg == "--has-rtti") {617        OS << (LLVM_HAS_RTTI ? "YES" : "NO") << '\n';618      } else if (Arg == "--shared-mode") {619        PrintSharedMode = true;620      } else if (Arg == "--obj-root") {621        MaybePrintQuoted(ActivePrefix);622        OS << '\n';623      } else if (Arg == "--ignore-libllvm") {624        LinkDyLib = false;625        LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto;626      } else if (Arg == "--link-shared") {627        LinkMode = LinkModeShared;628      } else if (Arg == "--link-static") {629        LinkMode = LinkModeStatic;630      } else if (Arg == "--help") {631        usage(false);632      } else if (Arg == "--quote-paths") {633        // Was already handled above this loop.634      } else {635        usage();636      }637    } else {638      Components.push_back(Arg);639    }640  }641 642  if (!HasAnyOption)643    usage();644 645  if (LinkMode == LinkModeShared && !DyLibExists && !BuiltSharedLibs) {646    WithColor::error(errs(), "llvm-config") << DyLibName << " is missing\n";647    return 1;648  }649 650  if (PrintLibs || PrintLibNames || PrintLibFiles || PrintSystemLibs ||651      PrintSharedMode) {652 653    if (PrintSharedMode && BuiltSharedLibs) {654      OS << "shared\n";655      return 0;656    }657 658    // If no components were specified, default to "all".659    if (Components.empty())660      Components.push_back("all");661 662    // Construct the list of all the required libraries.663    std::function<std::string(const StringRef &)>664        GetComponentLibraryPathFunction = [&](const StringRef &Name) {665          return GetComponentLibraryPath(Name, LinkMode == LinkModeShared);666        };667    std::vector<std::string> MissingLibs;668    std::vector<std::string> RequiredLibs = computeLibsForComponents(669        Components,670        /*IncludeNonInstalled=*/IsInDevelopmentTree, false,671        &GetComponentLibraryPathFunction, &MissingLibs, DirSep);672    if (!MissingLibs.empty()) {673      switch (LinkMode) {674      case LinkModeShared:675        if (LinkDyLib && !BuiltSharedLibs)676          break;677        // Using component shared libraries.678        for (auto &Lib : MissingLibs)679          WithColor::error(errs(), "llvm-config") << "missing: " << Lib << "\n";680        return 1;681      case LinkModeAuto:682        if (DyLibExists) {683          LinkMode = LinkModeShared;684          break;685        }686        WithColor::error(errs(), "llvm-config")687            << "component libraries and shared library\n\n";688        [[fallthrough]];689      case LinkModeStatic:690        for (auto &Lib : MissingLibs)691          WithColor::error(errs(), "llvm-config") << "missing: " << Lib << "\n";692        return 1;693      }694    } else if (LinkMode == LinkModeAuto) {695      LinkMode = LinkModeStatic;696    }697 698    if (PrintSharedMode) {699      std::unordered_set<std::string> FullDyLibComponents;700      std::vector<std::string> DyLibComponents =701          getAllDyLibComponents(IsInDevelopmentTree, false, DirSep);702 703      for (auto &Component : DyLibComponents)704        FullDyLibComponents.insert(Component);705      DyLibComponents.clear();706 707      for (auto &Lib : RequiredLibs) {708        if (!FullDyLibComponents.count(Lib)) {709          OS << "static\n";710          return 0;711        }712      }713      FullDyLibComponents.clear();714 715      if (LinkMode == LinkModeShared)716        OS << "shared\n";717      else718        OS << "static\n";719      return 0;720    }721 722    if (PrintLibs || PrintLibNames || PrintLibFiles) {723 724      auto PrintForLib = [&](const StringRef &Lib) {725        const bool Shared = LinkMode == LinkModeShared;726        std::string LibFileName;727        if (PrintLibNames) {728          LibFileName = GetComponentLibraryFileName(Lib, Shared);729        } else if (PrintLibFiles) {730          LibFileName = GetComponentLibraryPath(Lib, Shared);731        } else if (PrintLibs) {732          // On Windows, output full path to library without parameters.733          // Elsewhere, if this is a typical library name, include it using -l.734          if (HostTriple.isWindowsMSVCEnvironment()) {735            LibFileName = GetComponentLibraryPath(Lib, Shared);736          } else {737            LibFileName = "-l";738            StringRef LibName;739            if (GetComponentLibraryNameSlice(Lib, LibName)) {740              // Extract library name (remove prefix and suffix).741              LibFileName += LibName;742            } else {743              // Lib is already a library name without prefix and suffix.744              LibFileName += Lib;745            }746          }747        }748        if (!LibFileName.empty())749          MaybePrintQuoted(LibFileName);750      };751 752      if (LinkMode == LinkModeShared && LinkDyLib)753        PrintForLib(DyLibName);754      else755        interleave(RequiredLibs, OS, PrintForLib, " ");756      OS << '\n';757    }758 759    // Print SYSTEM_LIBS after --libs.760    // FIXME: Each LLVM component may have its dependent system libs.761    if (PrintSystemLibs) {762      // Output system libraries only if linking against a static763      // library (since the shared library links to all system libs764      // already)765      OS << (LinkMode == LinkModeStatic ? LLVM_SYSTEM_LIBS : "") << '\n';766    }767  } else if (!Components.empty()) {768    WithColor::error(errs(), "llvm-config")769        << "components given, but unused\n\n";770    usage();771  }772 773  return 0;774}775