summaryrefslogtreecommitdiff
path: root/tools/llvm-config-2
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2011-11-03 17:30:19 +0000
committerDaniel Dunbar <daniel@zuster.org>2011-11-03 17:30:19 +0000
commit62b2fea43df426179a81cdd2c7dc6bc2ff1008d3 (patch)
tree79489aaba448688dd0bd1252e17839a18509ddef /tools/llvm-config-2
parent7fdd291c91eb89801bc6dd0ce998b9d3b0d92d10 (diff)
downloadllvm-62b2fea43df426179a81cdd2c7dc6bc2ff1008d3.tar.gz
llvm-62b2fea43df426179a81cdd2c7dc6bc2ff1008d3.tar.bz2
llvm-62b2fea43df426179a81cdd2c7dc6bc2ff1008d3.tar.xz
llvm-config-2: Implement component dependency traversal, implement support for 'all', and fix a few other minor bugs.
- Still doesn't use actual generated component table, but that is now just a matter of wiring into the build system. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143617 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-config-2')
-rw-r--r--tools/llvm-config-2/llvm-config.cpp103
1 files changed, 90 insertions, 13 deletions
diff --git a/tools/llvm-config-2/llvm-config.cpp b/tools/llvm-config-2/llvm-config.cpp
index 35bda5026f..0d726d258d 100644
--- a/tools/llvm-config-2/llvm-config.cpp
+++ b/tools/llvm-config-2/llvm-config.cpp
@@ -17,6 +17,8 @@
//
//===----------------------------------------------------------------------===//
+#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"
@@ -26,6 +28,7 @@
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
+#include <set>
#include <vector>
using namespace llvm;
@@ -40,16 +43,88 @@ const char LLVM_CXXFLAGS[] = "FIXME";
const char LLVM_BUILDMODE[] = "FIXME";
const char LLVM_SYSTEM_LIBS[] = "FIXME";
-// FIXME: Include component table.
+// 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.
+//
+// FIXME: Include real component table.
struct AvailableComponent {
const char *Name;
-} AvailableComponents[1] = {};
-unsigned NumAvailableComponents = 0;
+ const char *Library;
+ const char *RequiredLibraries[1];
+} AvailableComponents[1] = {
+ { "all", 0, { } }
+};
+
+/// \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<AvailableComponent*> &ComponentMap,
+ std::set<StringRef> &VisitedComponents,
+ std::vector<StringRef> &RequiredLibs) {
+ // Add to the visited table.
+ if (!VisitedComponents.insert(Name).second) {
+ // We are done if the component has already been visited.
+ return;
+ }
+
+ // Otherwise, visit all the dependencies.
+ AvailableComponent *AC = ComponentMap.lookup(Name);
+ assert(AC && "Invalid component name!");
+
+ 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<StringRef> &Components,
std::vector<StringRef> &RequiredLibs) {
- // FIXME: Implement.
- RequiredLibs = Components;
+ std::set<StringRef> VisitedComponents;
+ std::vector<StringRef> ToVisit = Components;
+
+ // Build a map of component names to information.
+ StringMap<AvailableComponent*> 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) {
+ // Validate that the user supplied a valid component name.
+ if (!ComponentMap.count(Components[i])) {
+ llvm::errs() << "llvm-config: unknown component name: " << Components[i]
+ << "\n";
+ exit(1);
+ }
+
+ VisitComponent(Components[i], 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());
}
/* *** */
@@ -90,6 +165,7 @@ Typical components:\n\
exit(1);
}
+/// \brief Compute the path to the main executable.
llvm::sys::Path GetExecutablePath(const char *Argv0) {
// This just needs to be some symbol in the binary; C++ doesn't
// allow taking the address of ::main however.
@@ -191,9 +267,9 @@ int main(int argc, char **argv) {
} else if (Arg == "--libfiles") {
PrintLibFiles = true;
} else if (Arg == "--components") {
- for (unsigned j = 0; j != NumAvailableComponents; ++j) {
- if (j)
- OS << ' ';
+ OS << "all";
+ for (unsigned j = 0; j != array_lengthof(AvailableComponents); ++j) {
+ OS << ' ';
OS << AvailableComponents[j].Name;
}
OS << '\n';
@@ -235,21 +311,22 @@ int main(int argc, char **argv) {
if (i)
OS << ' ';
- if (PrintLibs) {
+ if (PrintLibNames) {
OS << Lib;
} else if (PrintLibFiles) {
- OS << ActiveLibDir << Lib;
- } else if (PrintLibNames) {
+ OS << ActiveLibDir << '/' << Lib;
+ } else if (PrintLibs) {
// If this is a typical library name, include it using -l.
if (Lib.startswith("lib") && Lib.endswith(".a")) {
OS << "-l" << Lib.slice(3, Lib.size()-2);
continue;
}
-
+
// Otherwise, print the full path.
- OS << ActiveLibDir << Lib;
+ OS << ActiveLibDir << '/' << Lib;
}
}
+ OS << '\n';
} else if (!Components.empty()) {
errs() << "llvm-config: error: components given, but unused\n\n";
usage();