35bda5026f0f2b6570dba7903b8565eed0a937a8
[oota-llvm.git] / tools / llvm-config-2 / llvm-config.cpp
1 //===-- llvm-config.cpp - LLVM project configuration utility --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This tool encapsulates information about an LLVM project configuration for
11 // use by other project's build environments (to determine installed path,
12 // available features, required libraries, etc.).
13 //
14 // Note that although this tool *may* be used by some parts of LLVM's build
15 // itself (i.e., the Makefiles use it to compute required libraries when linking
16 // tools), this tool is primarily designed to support external projects.
17 //
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/Config/config.h"
23 #include "llvm/Config/llvm-config.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/Path.h"
26 #include "llvm/Support/TargetRegistry.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include <cstdlib>
29 #include <vector>
30
31 using namespace llvm;
32
33 // FIXME: Need to get various bits of build time information.
34 const char LLVM_SRC_ROOT[] = "FIXME";
35 const char LLVM_OBJ_ROOT[] = "FIXME";
36 const char LLVM_CPPFLAGS[] = "FIXME";
37 const char LLVM_CFLAGS[] = "FIXME";
38 const char LLVM_LDFLAGS[] = "FIXME";
39 const char LLVM_CXXFLAGS[] = "FIXME";
40 const char LLVM_BUILDMODE[] = "FIXME";
41 const char LLVM_SYSTEM_LIBS[] = "FIXME";
42
43 // FIXME: Include component table.
44 struct AvailableComponent {
45   const char *Name;
46 } AvailableComponents[1] = {};
47 unsigned NumAvailableComponents = 0;
48
49 void ComputeLibsForComponents(const std::vector<StringRef> &Components,
50                               std::vector<StringRef> &RequiredLibs) {
51   // FIXME: Implement.
52   RequiredLibs = Components;
53 }
54
55 /* *** */
56
57 void usage() {
58   errs() << "\
59 usage: llvm-config <OPTION>... [<COMPONENT>...]\n\
60 \n\
61 Get various configuration information needed to compile programs which use\n\
62 LLVM.  Typically called from 'configure' scripts.  Examples:\n\
63   llvm-config --cxxflags\n\
64   llvm-config --ldflags\n\
65   llvm-config --libs engine bcreader scalaropts\n\
66 \n\
67 Options:\n\
68   --version         Print LLVM version.\n\
69   --prefix          Print the installation prefix.\n\
70   --src-root        Print the source root LLVM was built from.\n\
71   --obj-root        Print the object root used to build LLVM.\n\
72   --bindir          Directory containing LLVM executables.\n\
73   --includedir      Directory containing LLVM headers.\n\
74   --libdir          Directory containing LLVM libraries.\n\
75   --cppflags        C preprocessor flags for files that include LLVM headers.\n\
76   --cflags          C compiler flags for files that include LLVM headers.\n\
77   --cxxflags        C++ compiler flags for files that include LLVM headers.\n\
78   --ldflags         Print Linker flags.\n\
79   --libs            Libraries needed to link against LLVM components.\n\
80   --libnames        Bare library names for in-tree builds.\n\
81   --libfiles        Fully qualified library filenames for makefile depends.\n\
82   --components      List of all possible components.\n\
83   --targets-built   List of all targets currently built.\n\
84   --host-target     Target triple used to configure LLVM.\n\
85   --build-mode      Print build mode of LLVM tree (e.g. Debug or Release).\n\
86 Typical components:\n\
87   all               All LLVM libraries (default).\n\
88   backend           Either a native backend or the C backend.\n\
89   engine            Either a native JIT or a bitcode interpreter.\n";
90   exit(1);
91 }
92
93 llvm::sys::Path GetExecutablePath(const char *Argv0) {
94   // This just needs to be some symbol in the binary; C++ doesn't
95   // allow taking the address of ::main however.
96   void *P = (void*) (intptr_t) GetExecutablePath;
97   return llvm::sys::Path::GetMainExecutable(Argv0, P);
98 }
99
100 int main(int argc, char **argv) {
101   std::vector<StringRef> Components;
102   bool PrintLibs = false, PrintLibNames = false, PrintLibFiles = false;
103   bool HasAnyOption = false;
104
105   // llvm-config is designed to support being run both from a development tree
106   // and from an installed path. We try and auto-detect which case we are in so
107   // that we can report the correct information when run from a development
108   // tree.
109   bool IsInDevelopmentTree, DevelopmentTreeLayoutIsCMakeStyle;
110   llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0]).str());
111   std::string CurrentExecPrefix;
112
113   // Create an absolute path, and pop up one directory (we expect to be inside a
114   // bin dir).
115   sys::fs::make_absolute(CurrentPath);
116   CurrentExecPrefix = sys::path::parent_path(
117     sys::path::parent_path(CurrentPath)).str();
118
119   // Check to see if we are inside a development tree by comparing to possible
120   // locations (prefix style or CMake style). This could be wrong in the face of
121   // symbolic links, but is good enough.
122   if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE) {
123     IsInDevelopmentTree = true;
124     DevelopmentTreeLayoutIsCMakeStyle = false;
125   } else if (CurrentExecPrefix == std::string(LLVM_OBJ_ROOT) + "/bin") {
126     IsInDevelopmentTree = true;
127     DevelopmentTreeLayoutIsCMakeStyle = true;
128   } else {
129     IsInDevelopmentTree = false;
130   }
131
132   // Compute various directory locations based on the derived location
133   // information.
134   std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir;
135   std::string ActiveIncludeOption;
136   if (IsInDevelopmentTree) {
137     ActivePrefix = CurrentExecPrefix;
138
139     // CMake organizes the products differently than a normal prefix style
140     // layout.
141     if (DevelopmentTreeLayoutIsCMakeStyle) {
142       ActiveIncludeDir = std::string(LLVM_OBJ_ROOT) + "/include";
143       ActiveBinDir = std::string(LLVM_OBJ_ROOT) + "/bin/" + LLVM_BUILDMODE;
144       ActiveLibDir = std::string(LLVM_OBJ_ROOT) + "/lib/" + LLVM_BUILDMODE;
145     } else {
146         ActiveIncludeDir = std::string(LLVM_OBJ_ROOT) + "/include";
147       ActiveBinDir = std::string(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE + "/bin";
148       ActiveLibDir = std::string(LLVM_OBJ_ROOT) + "/" + LLVM_BUILDMODE + "/lib";
149     }
150
151     // We need to include files from both the source and object trees.
152     ActiveIncludeOption = ("-I" + ActiveIncludeDir + " " +
153                            "-I" + LLVM_OBJ_ROOT + "/include");
154   } else {
155     ActivePrefix = CurrentExecPrefix;
156     ActiveIncludeDir = ActivePrefix + "/include";
157     ActiveBinDir = ActivePrefix + "/bin";
158     ActiveLibDir = ActivePrefix + "/lib";
159     ActiveIncludeOption = "-I" + ActiveIncludeDir;
160   }
161
162   raw_ostream &OS = outs();
163   for (int i = 1; i != argc; ++i) {
164     StringRef Arg = argv[i];
165
166     if (Arg.startswith("-")) {
167       HasAnyOption = true;
168       if (Arg == "--version") {
169         OS << PACKAGE_VERSION << '\n';
170       } else if (Arg == "--prefix") {
171         OS << ActivePrefix << '\n';
172       } else if (Arg == "--bindir") {
173         OS << ActiveBinDir << '\n';
174       } else if (Arg == "--includedir") {
175         OS << ActiveIncludeDir << '\n';
176       } else if (Arg == "--libdir") {
177         OS << ActiveLibDir << '\n';
178       } else if (Arg == "--cppflags") {
179         OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << '\n';
180       } else if (Arg == "--cflags") {
181         OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << '\n';
182       } else if (Arg == "--cxxflags") {
183         OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n';
184       } else if (Arg == "--ldflags") {
185         OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS
186            << ' ' << LLVM_SYSTEM_LIBS << '\n';
187       } else if (Arg == "--libs") {
188         PrintLibs = true;
189       } else if (Arg == "--libnames") {
190         PrintLibNames = true;
191       } else if (Arg == "--libfiles") {
192         PrintLibFiles = true;
193       } else if (Arg == "--components") {
194         for (unsigned j = 0; j != NumAvailableComponents; ++j) {
195           if (j)
196             OS << ' ';
197           OS << AvailableComponents[j].Name;
198         }
199         OS << '\n';
200       } else if (Arg == "--targets-built") {
201         bool First = true;
202         for (TargetRegistry::iterator I = TargetRegistry::begin(),
203                E = TargetRegistry::end(); I != E; First = false, ++I) {
204           if (!First)
205             OS << ' ';
206           OS << I->getName();
207         }
208         OS << '\n';
209       } else if (Arg == "--host-target") {
210         OS << LLVM_DEFAULT_TARGET_TRIPLE << '\n';
211       } else if (Arg == "--build-mode") {
212         OS << LLVM_BUILDMODE << '\n';
213       } else if (Arg == "--obj-root") {
214         OS << LLVM_OBJ_ROOT << '\n';
215       } else if (Arg == "--src-root") {
216         OS << LLVM_SRC_ROOT << '\n';
217       } else {
218         usage();
219       }
220     } else {
221       Components.push_back(Arg);
222     }
223   }
224
225   if (!HasAnyOption)
226     usage();
227
228   if (PrintLibs || PrintLibNames || PrintLibFiles) {
229     // Construct the list of all the required libraries.
230     std::vector<StringRef> RequiredLibs;
231     ComputeLibsForComponents(Components, RequiredLibs);
232
233     for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) {
234       StringRef Lib = RequiredLibs[i];
235       if (i)
236         OS << ' ';
237
238       if (PrintLibs) {
239         OS << Lib;
240       } else if (PrintLibFiles) {
241         OS << ActiveLibDir << Lib;
242       } else if (PrintLibNames) {
243         // If this is a typical library name, include it using -l.
244         if (Lib.startswith("lib") && Lib.endswith(".a")) {
245           OS << "-l" << Lib.slice(3, Lib.size()-2);
246           continue;
247         }
248         
249         // Otherwise, print the full path.
250         OS << ActiveLibDir << Lib;
251       }
252     }
253   } else if (!Components.empty()) {
254     errs() << "llvm-config: error: components given, but unused\n\n";
255     usage();
256   }
257
258   return 0;
259 }