llvm-config: Add --has-rtti option
[oota-llvm.git] / tools / llvm-config / llvm-config.cpp
index 2bb0aebc80eaa28df20964127c62ca497f377a76..8bf2680d3918b32ef457396d19853041c6eda7fd 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Config/config.h"
 #include "llvm/Config/llvm-config.h"
@@ -54,7 +55,8 @@ using namespace llvm;
 static void VisitComponent(StringRef Name,
                            const StringMap<AvailableComponent*> &ComponentMap,
                            std::set<AvailableComponent*> &VisitedComponents,
-                           std::vector<StringRef> &RequiredLibs) {
+                           std::vector<StringRef> &RequiredLibs,
+                           bool IncludeNonInstalled) {
   // Lookup the component.
   AvailableComponent *AC = ComponentMap.lookup(Name);
   assert(AC && "Invalid component name!");
@@ -65,10 +67,14 @@ static void VisitComponent(StringRef Name,
     return;
   }
 
+  // Only include non-installed components if requested.
+  if (!AC->IsInstalled && !IncludeNonInstalled)
+    return;
+
   // Otherwise, visit all the dependencies.
   for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) {
     VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents,
-                   RequiredLibs);
+                   RequiredLibs, IncludeNonInstalled);
   }
 
   // Add to the required library list.
@@ -83,8 +89,11 @@ static void VisitComponent(StringRef Name,
 /// \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) {
+/// \param IncludeNonInstalled - Whether non-installed components should be
+/// reported.
+static void ComputeLibsForComponents(const std::vector<StringRef> &Components,
+                                     std::vector<StringRef> &RequiredLibs,
+                                     bool IncludeNonInstalled) {
   std::set<AvailableComponent*> VisitedComponents;
 
   // Build a map of component names to information.
@@ -107,7 +116,7 @@ void ComputeLibsForComponents(const std::vector<StringRef> &Components,
     }
 
     VisitComponent(ComponentLower, ComponentMap, VisitedComponents,
-                   RequiredLibs);
+                   RequiredLibs, IncludeNonInstalled);
   }
 
   // The list is now ordered with leafs first, we want the libraries to printed
@@ -117,7 +126,7 @@ void ComputeLibsForComponents(const std::vector<StringRef> &Components,
 
 /* *** */
 
-void usage() {
+static void usage() {
   errs() << "\
 usage: llvm-config <OPTION>... [<COMPONENT>...]\n\
 \n\
@@ -139,6 +148,7 @@ Options:\n\
   --cflags          C compiler flags for files that include LLVM headers.\n\
   --cxxflags        C++ compiler flags for files that include LLVM headers.\n\
   --ldflags         Print Linker flags.\n\
+  --system-libs     System Libraries needed to link against LLVM components.\n\
   --libs            Libraries needed to link against LLVM components.\n\
   --libnames        Bare library names for in-tree builds.\n\
   --libfiles        Fully qualified library filenames for makefile depends.\n\
@@ -146,6 +156,9 @@ Options:\n\
   --targets-built   List of all targets currently built.\n\
   --host-target     Target triple used to configure LLVM.\n\
   --build-mode      Print build mode of LLVM tree (e.g. Debug or Release).\n\
+  --assertion-mode  Print assertion mode of LLVM tree (ON or OFF).\n\
+  --build-system    Print the build system used to build LLVM (autoconf or cmake).\n\
+  --has-rtti        Print whether or not LLVM was built with rtti (YES or NO).\n\
 Typical components:\n\
   all               All LLVM libraries (default).\n\
   engine            Either a native JIT or a bitcode interpreter.\n";
@@ -153,27 +166,36 @@ Typical components:\n\
 }
 
 /// \brief Compute the path to the main executable.
-llvm::sys::Path GetExecutablePath(const char *Argv0) {
+std::string GetExecutablePath(const char *Argv0) {
   // This just needs to be some symbol in the binary; C++ doesn't
   // allow taking the address of ::main however.
   void *P = (void*) (intptr_t) GetExecutablePath;
-  return llvm::sys::Path::GetMainExecutable(Argv0, P);
+  return llvm::sys::fs::getMainExecutable(Argv0, P);
 }
 
 int main(int argc, char **argv) {
   std::vector<StringRef> Components;
   bool PrintLibs = false, PrintLibNames = false, PrintLibFiles = false;
+  bool PrintSystemLibs = false;
   bool HasAnyOption = false;
 
   // llvm-config is designed to support being run both from a development tree
   // and from an installed path. We try and auto-detect which case we are in so
   // that we can report the correct information when run from a development
   // tree.
-  bool IsInDevelopmentTree, DevelopmentTreeLayoutIsCMakeStyle;
-  llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0]).str());
+  bool IsInDevelopmentTree;
+  enum { MakefileStyle, CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout;
+  llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0]));
   std::string CurrentExecPrefix;
   std::string ActiveObjRoot;
 
+  // If CMAKE_CFG_INTDIR is given, honor it as build mode.
+  char const *build_mode = LLVM_BUILDMODE;
+#if defined(CMAKE_CFG_INTDIR)
+  if (!(CMAKE_CFG_INTDIR[0] == '.' && CMAKE_CFG_INTDIR[1] == '\0'))
+    build_mode = CMAKE_CFG_INTDIR;
+#endif
+
   // Create an absolute path, and pop up one directory (we expect to be inside a
   // bin dir).
   sys::fs::make_absolute(CurrentPath);
@@ -181,11 +203,11 @@ int main(int argc, char **argv) {
     sys::path::parent_path(CurrentPath)).str();
 
   // Check to see if we are inside a development tree by comparing to possible
-  // locations (prefix style or CMake style). This could be wrong in the face of
-  // symbolic links, but is good enough.
-  if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE) {
+  // locations (prefix style or CMake style).
+  if (sys::fs::equivalent(CurrentExecPrefix,
+                          Twine(LLVM_OBJ_ROOT) + "/" + build_mode)) {
     IsInDevelopmentTree = true;
-    DevelopmentTreeLayoutIsCMakeStyle = false;
+    DevelopmentTreeLayout = MakefileStyle;
 
     // If we are in a development tree, then check if we are in a BuildTools
     // directory. This indicates we are built for the build triple, but we
@@ -195,12 +217,18 @@ int main(int argc, char **argv) {
     } else {
       ActiveObjRoot = LLVM_OBJ_ROOT;
     }
-  } else if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/bin") {
+  } else if (sys::fs::equivalent(CurrentExecPrefix, LLVM_OBJ_ROOT)) {
     IsInDevelopmentTree = true;
-    DevelopmentTreeLayoutIsCMakeStyle = true;
+    DevelopmentTreeLayout = CMakeStyle;
+    ActiveObjRoot = LLVM_OBJ_ROOT;
+  } else if (sys::fs::equivalent(CurrentExecPrefix,
+                                 Twine(LLVM_OBJ_ROOT) + "/bin")) {
+    IsInDevelopmentTree = true;
+    DevelopmentTreeLayout = CMakeBuildModeStyle;
     ActiveObjRoot = LLVM_OBJ_ROOT;
   } else {
     IsInDevelopmentTree = false;
+    DevelopmentTreeLayout = MakefileStyle; // Initialized to avoid warnings.
   }
 
   // Compute various directory locations based on the derived location
@@ -213,12 +241,23 @@ int main(int argc, char **argv) {
 
     // CMake organizes the products differently than a normal prefix style
     // layout.
-    if (DevelopmentTreeLayoutIsCMakeStyle) {
-      ActiveBinDir = ActiveObjRoot + "/bin/" + LLVM_BUILDMODE;
-      ActiveLibDir = ActiveObjRoot + "/lib/" + LLVM_BUILDMODE;
-    } else {
-      ActiveBinDir = ActiveObjRoot + "/" + LLVM_BUILDMODE + "/bin";
-      ActiveLibDir = ActiveObjRoot + "/" + LLVM_BUILDMODE + "/lib";
+    switch (DevelopmentTreeLayout) {
+    case MakefileStyle:
+      ActivePrefix = ActiveObjRoot;
+      ActiveBinDir = ActiveObjRoot + "/" + build_mode + "/bin";
+      ActiveLibDir =
+          ActiveObjRoot + "/" + build_mode + "/lib" + LLVM_LIBDIR_SUFFIX;
+      break;
+    case CMakeStyle:
+      ActiveBinDir = ActiveObjRoot + "/bin";
+      ActiveLibDir = ActiveObjRoot + "/lib" + LLVM_LIBDIR_SUFFIX;
+      break;
+    case CMakeBuildModeStyle:
+      ActivePrefix = ActiveObjRoot;
+      ActiveBinDir = ActiveObjRoot + "/bin/" + build_mode;
+      ActiveLibDir =
+          ActiveObjRoot + "/lib" + LLVM_LIBDIR_SUFFIX + "/" + build_mode;
+      break;
     }
 
     // We need to include files from both the source and object trees.
@@ -228,7 +267,7 @@ int main(int argc, char **argv) {
     ActivePrefix = CurrentExecPrefix;
     ActiveIncludeDir = ActivePrefix + "/include";
     ActiveBinDir = ActivePrefix + "/bin";
-    ActiveLibDir = ActivePrefix + "/lib";
+    ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX;
     ActiveIncludeOption = "-I" + ActiveIncludeDir;
   }
 
@@ -255,8 +294,9 @@ int main(int argc, char **argv) {
       } else if (Arg == "--cxxflags") {
         OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n';
       } else if (Arg == "--ldflags") {
-        OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS
-           << ' ' << LLVM_SYSTEM_LIBS << '\n';
+        OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n';
+      } else if (Arg == "--system-libs") {
+        PrintSystemLibs = true;
       } else if (Arg == "--libs") {
         PrintLibs = true;
       } else if (Arg == "--libnames") {
@@ -265,6 +305,10 @@ int main(int argc, char **argv) {
         PrintLibFiles = true;
       } else if (Arg == "--components") {
         for (unsigned j = 0; j != array_lengthof(AvailableComponents); ++j) {
+          // Only include non-installed components when in a development tree.
+          if (!AvailableComponents[j].IsInstalled && !IsInDevelopmentTree)
+            continue;
+
           OS << ' ';
           OS << AvailableComponents[j].Name;
         }
@@ -272,11 +316,21 @@ int main(int argc, char **argv) {
       } else if (Arg == "--targets-built") {
         OS << LLVM_TARGETS_BUILT << '\n';
       } else if (Arg == "--host-target") {
-        OS << LLVM_DEFAULT_TARGET_TRIPLE << '\n';
+        OS << Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE) << '\n';
       } else if (Arg == "--build-mode") {
-        OS << LLVM_BUILDMODE << '\n';
+        OS << build_mode << '\n';
+      } else if (Arg == "--assertion-mode") {
+#if defined(NDEBUG)
+        OS << "OFF\n";
+#else
+        OS << "ON\n";
+#endif
+      } else if (Arg == "--build-system") {
+        OS << LLVM_BUILD_SYSTEM << '\n';
+      } else if (Arg == "--has-rtti") {
+        OS << LLVM_HAS_RTTI << '\n';
       } else if (Arg == "--obj-root") {
-        OS << LLVM_OBJ_ROOT << '\n';
+        OS << ActivePrefix << '\n';
       } else if (Arg == "--src-root") {
         OS << LLVM_SRC_ROOT << '\n';
       } else {
@@ -290,36 +344,44 @@ int main(int argc, char **argv) {
   if (!HasAnyOption)
     usage();
 
-  if (PrintLibs || PrintLibNames || PrintLibFiles) {
+  if (PrintLibs || PrintLibNames || PrintLibFiles || PrintSystemLibs) {
     // If no components were specified, default to "all".
     if (Components.empty())
       Components.push_back("all");
 
     // Construct the list of all the required libraries.
     std::vector<StringRef> RequiredLibs;
-    ComputeLibsForComponents(Components, RequiredLibs);
-
-    for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) {
-      StringRef Lib = RequiredLibs[i];
-      if (i)
-        OS << ' ';
-
-      if (PrintLibNames) {
-        OS << Lib;
-      } else if (PrintLibFiles) {
-        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;
-        }
+    ComputeLibsForComponents(Components, RequiredLibs,
+                             /*IncludeNonInstalled=*/IsInDevelopmentTree);
+
+    if (PrintLibs || PrintLibNames || PrintLibFiles) {
+      for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) {
+        StringRef Lib = RequiredLibs[i];
+        if (i)
+          OS << ' ';
 
-        // Otherwise, print the full path.
-        OS << ActiveLibDir << '/' << Lib;
+        if (PrintLibNames) {
+          OS << Lib;
+        } else if (PrintLibFiles) {
+          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 << '\n';
     }
-    OS << '\n';
+
+    // Print SYSTEM_LIBS after --libs.
+    // FIXME: Each LLVM component may have its dependent system libs.
+    if (PrintSystemLibs)
+      OS << LLVM_SYSTEM_LIBS << '\n';
   } else if (!Components.empty()) {
     errs() << "llvm-config: error: components given, but unused\n\n";
     usage();