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