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