From 2662c83a594b5df8deef2a540595a5faa72cfbdc Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 29 Nov 2011 22:56:31 +0000 Subject: llvm-config: Replace with C++ version (was llvm-config-2). - Reapply of r144300, with lots of fixes/migration easement in between. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145449 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-config/llvm-config.cpp | 335 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 tools/llvm-config/llvm-config.cpp (limited to 'tools/llvm-config/llvm-config.cpp') diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp new file mode 100644 index 0000000000..fddd481230 --- /dev/null +++ b/tools/llvm-config/llvm-config.cpp @@ -0,0 +1,335 @@ +//===-- llvm-config.cpp - LLVM project configuration utility --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tool encapsulates information about an LLVM project configuration for +// use by other project's build environments (to determine installed path, +// available features, required libraries, etc.). +// +// Note that although this tool *may* be used by some parts of LLVM's build +// itself (i.e., the Makefiles use it to compute required libraries when linking +// tools), this tool is primarily designed to support external projects. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include + +using namespace llvm; + +// Include the build time variables we can report to the user. This is generated +// at build time from the BuildVariables.inc.in file by the build system. +#include "BuildVariables.inc" + +// Include the component table. This creates an array of struct +// AvailableComponent entries, which record the component name, library name, +// and required components for all of the available libraries. +// +// Not all components define a library, we also use "library groups" as a way to +// create entries for pseudo groups like x86 or all-targets. +#include "LibraryDependencies.inc" + +/// \brief Traverse a single component adding to the topological ordering in +/// \arg RequiredLibs. +/// +/// \param Name - The component to traverse. +/// \param ComponentMap - A prebuilt map of component names to descriptors. +/// \param VisitedComponents [in] [out] - The set of already visited components. +/// \param RequiredLibs [out] - The ordered list of required libraries. +static void VisitComponent(StringRef Name, + const StringMap &ComponentMap, + std::set &VisitedComponents, + std::vector &RequiredLibs) { + // Lookup the component. + AvailableComponent *AC = ComponentMap.lookup(Name); + assert(AC && "Invalid component name!"); + + // Add to the visited table. + if (!VisitedComponents.insert(AC).second) { + // We are done if the component has already been visited. + return; + } + + // Otherwise, visit all the dependencies. + for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) { + VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents, + RequiredLibs); + } + + // Add to the required library list. + if (AC->Library) + RequiredLibs.push_back(AC->Library); +} + +/// \brief Compute the list of required libraries for a given list of +/// components, in an order suitable for passing to a linker (that is, libraries +/// appear prior to their dependencies). +/// +/// \param Components - The names of the components to find libraries for. +/// \param RequiredLibs [out] - On return, the ordered list of libraries that +/// are required to link the given components. +void ComputeLibsForComponents(const std::vector &Components, + std::vector &RequiredLibs) { + std::set VisitedComponents; + + // Build a map of component names to information. + StringMap ComponentMap; + for (unsigned i = 0; i != array_lengthof(AvailableComponents); ++i) { + AvailableComponent *AC = &AvailableComponents[i]; + ComponentMap[AC->Name] = AC; + } + + // Visit the components. + for (unsigned i = 0, e = Components.size(); i != e; ++i) { + // Users are allowed to provide mixed case component names. + std::string ComponentLower = Components[i].lower(); + + // Validate that the user supplied a valid component name. + if (!ComponentMap.count(ComponentLower)) { + llvm::errs() << "llvm-config: unknown component name: " << Components[i] + << "\n"; + exit(1); + } + + VisitComponent(ComponentLower, ComponentMap, VisitedComponents, + RequiredLibs); + } + + // The list is now ordered with leafs first, we want the libraries to printed + // in the reverse order of dependency. + std::reverse(RequiredLibs.begin(), RequiredLibs.end()); +} + +/* *** */ + +void usage() { + errs() << "\ +usage: llvm-config