]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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/STLExtras.h" | |
21 | #include "llvm/ADT/StringMap.h" | |
22 | #include "llvm/ADT/StringRef.h" | |
1a4d82fc | 23 | #include "llvm/ADT/Triple.h" |
223e47cc LB |
24 | #include "llvm/ADT/Twine.h" |
25 | #include "llvm/Config/config.h" | |
26 | #include "llvm/Config/llvm-config.h" | |
27 | #include "llvm/Support/FileSystem.h" | |
28 | #include "llvm/Support/Path.h" | |
29 | #include "llvm/Support/raw_ostream.h" | |
30 | #include <cstdlib> | |
31 | #include <set> | |
32 | #include <vector> | |
33 | ||
34 | using namespace llvm; | |
35 | ||
36 | // Include the build time variables we can report to the user. This is generated | |
37 | // at build time from the BuildVariables.inc.in file by the build system. | |
38 | #include "BuildVariables.inc" | |
39 | ||
40 | // Include the component table. This creates an array of struct | |
41 | // AvailableComponent entries, which record the component name, library name, | |
42 | // and required components for all of the available libraries. | |
43 | // | |
44 | // Not all components define a library, we also use "library groups" as a way to | |
45 | // create entries for pseudo groups like x86 or all-targets. | |
46 | #include "LibraryDependencies.inc" | |
47 | ||
48 | /// \brief Traverse a single component adding to the topological ordering in | |
49 | /// \arg RequiredLibs. | |
50 | /// | |
51 | /// \param Name - The component to traverse. | |
52 | /// \param ComponentMap - A prebuilt map of component names to descriptors. | |
53 | /// \param VisitedComponents [in] [out] - The set of already visited components. | |
54 | /// \param RequiredLibs [out] - The ordered list of required libraries. | |
55 | static void VisitComponent(StringRef Name, | |
56 | const StringMap<AvailableComponent*> &ComponentMap, | |
57 | std::set<AvailableComponent*> &VisitedComponents, | |
58 | std::vector<StringRef> &RequiredLibs, | |
59 | bool IncludeNonInstalled) { | |
60 | // Lookup the component. | |
61 | AvailableComponent *AC = ComponentMap.lookup(Name); | |
62 | assert(AC && "Invalid component name!"); | |
63 | ||
64 | // Add to the visited table. | |
65 | if (!VisitedComponents.insert(AC).second) { | |
66 | // We are done if the component has already been visited. | |
67 | return; | |
68 | } | |
69 | ||
70 | // Only include non-installed components if requested. | |
71 | if (!AC->IsInstalled && !IncludeNonInstalled) | |
72 | return; | |
73 | ||
74 | // Otherwise, visit all the dependencies. | |
75 | for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) { | |
76 | VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents, | |
77 | RequiredLibs, IncludeNonInstalled); | |
78 | } | |
79 | ||
80 | // Add to the required library list. | |
81 | if (AC->Library) | |
82 | RequiredLibs.push_back(AC->Library); | |
83 | } | |
84 | ||
85 | /// \brief Compute the list of required libraries for a given list of | |
86 | /// components, in an order suitable for passing to a linker (that is, libraries | |
87 | /// appear prior to their dependencies). | |
88 | /// | |
89 | /// \param Components - The names of the components to find libraries for. | |
90 | /// \param RequiredLibs [out] - On return, the ordered list of libraries that | |
91 | /// are required to link the given components. | |
92 | /// \param IncludeNonInstalled - Whether non-installed components should be | |
93 | /// reported. | |
94 | void ComputeLibsForComponents(const std::vector<StringRef> &Components, | |
95 | std::vector<StringRef> &RequiredLibs, | |
96 | bool IncludeNonInstalled) { | |
97 | std::set<AvailableComponent*> VisitedComponents; | |
98 | ||
99 | // Build a map of component names to information. | |
100 | StringMap<AvailableComponent*> ComponentMap; | |
101 | for (unsigned i = 0; i != array_lengthof(AvailableComponents); ++i) { | |
102 | AvailableComponent *AC = &AvailableComponents[i]; | |
103 | ComponentMap[AC->Name] = AC; | |
104 | } | |
105 | ||
106 | // Visit the components. | |
107 | for (unsigned i = 0, e = Components.size(); i != e; ++i) { | |
108 | // Users are allowed to provide mixed case component names. | |
109 | std::string ComponentLower = Components[i].lower(); | |
110 | ||
111 | // Validate that the user supplied a valid component name. | |
112 | if (!ComponentMap.count(ComponentLower)) { | |
113 | llvm::errs() << "llvm-config: unknown component name: " << Components[i] | |
114 | << "\n"; | |
115 | exit(1); | |
116 | } | |
117 | ||
118 | VisitComponent(ComponentLower, ComponentMap, VisitedComponents, | |
119 | RequiredLibs, IncludeNonInstalled); | |
120 | } | |
121 | ||
122 | // The list is now ordered with leafs first, we want the libraries to printed | |
123 | // in the reverse order of dependency. | |
124 | std::reverse(RequiredLibs.begin(), RequiredLibs.end()); | |
125 | } | |
126 | ||
127 | /* *** */ | |
128 | ||
129 | void usage() { | |
130 | errs() << "\ | |
131 | usage: llvm-config <OPTION>... [<COMPONENT>...]\n\ | |
132 | \n\ | |
133 | Get various configuration information needed to compile programs which use\n\ | |
134 | LLVM. Typically called from 'configure' scripts. Examples:\n\ | |
135 | llvm-config --cxxflags\n\ | |
136 | llvm-config --ldflags\n\ | |
137 | llvm-config --libs engine bcreader scalaropts\n\ | |
138 | \n\ | |
139 | Options:\n\ | |
140 | --version Print LLVM version.\n\ | |
141 | --prefix Print the installation prefix.\n\ | |
142 | --src-root Print the source root LLVM was built from.\n\ | |
143 | --obj-root Print the object root used to build LLVM.\n\ | |
144 | --bindir Directory containing LLVM executables.\n\ | |
145 | --includedir Directory containing LLVM headers.\n\ | |
146 | --libdir Directory containing LLVM libraries.\n\ | |
147 | --cppflags C preprocessor flags for files that include LLVM headers.\n\ | |
148 | --cflags C compiler flags for files that include LLVM headers.\n\ | |
149 | --cxxflags C++ compiler flags for files that include LLVM headers.\n\ | |
150 | --ldflags Print Linker flags.\n\ | |
1a4d82fc | 151 | --system-libs System Libraries needed to link against LLVM components.\n\ |
223e47cc LB |
152 | --libs Libraries needed to link against LLVM components.\n\ |
153 | --libnames Bare library names for in-tree builds.\n\ | |
154 | --libfiles Fully qualified library filenames for makefile depends.\n\ | |
155 | --components List of all possible components.\n\ | |
156 | --targets-built List of all targets currently built.\n\ | |
157 | --host-target Target triple used to configure LLVM.\n\ | |
158 | --build-mode Print build mode of LLVM tree (e.g. Debug or Release).\n\ | |
1a4d82fc | 159 | --assertion-mode Print assertion mode of LLVM tree (ON or OFF).\n\ |
223e47cc LB |
160 | Typical components:\n\ |
161 | all All LLVM libraries (default).\n\ | |
162 | engine Either a native JIT or a bitcode interpreter.\n"; | |
163 | exit(1); | |
164 | } | |
165 | ||
166 | /// \brief Compute the path to the main executable. | |
1a4d82fc | 167 | std::string GetExecutablePath(const char *Argv0) { |
223e47cc LB |
168 | // This just needs to be some symbol in the binary; C++ doesn't |
169 | // allow taking the address of ::main however. | |
170 | void *P = (void*) (intptr_t) GetExecutablePath; | |
1a4d82fc | 171 | return llvm::sys::fs::getMainExecutable(Argv0, P); |
223e47cc LB |
172 | } |
173 | ||
174 | int main(int argc, char **argv) { | |
175 | std::vector<StringRef> Components; | |
176 | bool PrintLibs = false, PrintLibNames = false, PrintLibFiles = false; | |
1a4d82fc | 177 | bool PrintSystemLibs = false; |
223e47cc LB |
178 | bool HasAnyOption = false; |
179 | ||
180 | // llvm-config is designed to support being run both from a development tree | |
181 | // and from an installed path. We try and auto-detect which case we are in so | |
182 | // that we can report the correct information when run from a development | |
183 | // tree. | |
184 | bool IsInDevelopmentTree; | |
185 | enum { MakefileStyle, CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout; | |
1a4d82fc | 186 | llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0])); |
223e47cc LB |
187 | std::string CurrentExecPrefix; |
188 | std::string ActiveObjRoot; | |
189 | ||
1a4d82fc JJ |
190 | // If CMAKE_CFG_INTDIR is given, honor it as build mode. |
191 | char const *build_mode = LLVM_BUILDMODE; | |
192 | #if defined(CMAKE_CFG_INTDIR) | |
193 | if (!(CMAKE_CFG_INTDIR[0] == '.' && CMAKE_CFG_INTDIR[1] == '\0')) | |
194 | build_mode = CMAKE_CFG_INTDIR; | |
195 | #endif | |
196 | ||
223e47cc LB |
197 | // Create an absolute path, and pop up one directory (we expect to be inside a |
198 | // bin dir). | |
199 | sys::fs::make_absolute(CurrentPath); | |
200 | CurrentExecPrefix = sys::path::parent_path( | |
201 | sys::path::parent_path(CurrentPath)).str(); | |
202 | ||
203 | // Check to see if we are inside a development tree by comparing to possible | |
204 | // locations (prefix style or CMake style). | |
205 | if (sys::fs::equivalent(CurrentExecPrefix, | |
1a4d82fc | 206 | Twine(LLVM_OBJ_ROOT) + "/" + build_mode)) { |
223e47cc LB |
207 | IsInDevelopmentTree = true; |
208 | DevelopmentTreeLayout = MakefileStyle; | |
209 | ||
210 | // If we are in a development tree, then check if we are in a BuildTools | |
211 | // directory. This indicates we are built for the build triple, but we | |
212 | // always want to provide information for the host triple. | |
213 | if (sys::path::filename(LLVM_OBJ_ROOT) == "BuildTools") { | |
214 | ActiveObjRoot = sys::path::parent_path(LLVM_OBJ_ROOT); | |
215 | } else { | |
216 | ActiveObjRoot = LLVM_OBJ_ROOT; | |
217 | } | |
218 | } else if (sys::fs::equivalent(CurrentExecPrefix, LLVM_OBJ_ROOT)) { | |
219 | IsInDevelopmentTree = true; | |
220 | DevelopmentTreeLayout = CMakeStyle; | |
221 | ActiveObjRoot = LLVM_OBJ_ROOT; | |
222 | } else if (sys::fs::equivalent(CurrentExecPrefix, | |
223 | Twine(LLVM_OBJ_ROOT) + "/bin")) { | |
224 | IsInDevelopmentTree = true; | |
225 | DevelopmentTreeLayout = CMakeBuildModeStyle; | |
226 | ActiveObjRoot = LLVM_OBJ_ROOT; | |
227 | } else { | |
228 | IsInDevelopmentTree = false; | |
229 | DevelopmentTreeLayout = MakefileStyle; // Initialized to avoid warnings. | |
230 | } | |
231 | ||
232 | // Compute various directory locations based on the derived location | |
233 | // information. | |
234 | std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir; | |
235 | std::string ActiveIncludeOption; | |
236 | if (IsInDevelopmentTree) { | |
237 | ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include"; | |
238 | ActivePrefix = CurrentExecPrefix; | |
239 | ||
240 | // CMake organizes the products differently than a normal prefix style | |
241 | // layout. | |
242 | switch (DevelopmentTreeLayout) { | |
243 | case MakefileStyle: | |
1a4d82fc JJ |
244 | ActivePrefix = ActiveObjRoot; |
245 | ActiveBinDir = ActiveObjRoot + "/" + build_mode + "/bin"; | |
85aaf69f SL |
246 | ActiveLibDir = |
247 | ActiveObjRoot + "/" + build_mode + "/lib" + LLVM_LIBDIR_SUFFIX; | |
223e47cc LB |
248 | break; |
249 | case CMakeStyle: | |
250 | ActiveBinDir = ActiveObjRoot + "/bin"; | |
85aaf69f | 251 | ActiveLibDir = ActiveObjRoot + "/lib" + LLVM_LIBDIR_SUFFIX; |
223e47cc LB |
252 | break; |
253 | case CMakeBuildModeStyle: | |
1a4d82fc JJ |
254 | ActivePrefix = ActiveObjRoot; |
255 | ActiveBinDir = ActiveObjRoot + "/bin/" + build_mode; | |
85aaf69f SL |
256 | ActiveLibDir = |
257 | ActiveObjRoot + "/lib" + LLVM_LIBDIR_SUFFIX + "/" + build_mode; | |
223e47cc LB |
258 | break; |
259 | } | |
260 | ||
261 | // We need to include files from both the source and object trees. | |
262 | ActiveIncludeOption = ("-I" + ActiveIncludeDir + " " + | |
263 | "-I" + ActiveObjRoot + "/include"); | |
264 | } else { | |
265 | ActivePrefix = CurrentExecPrefix; | |
266 | ActiveIncludeDir = ActivePrefix + "/include"; | |
267 | ActiveBinDir = ActivePrefix + "/bin"; | |
85aaf69f | 268 | ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX; |
223e47cc LB |
269 | ActiveIncludeOption = "-I" + ActiveIncludeDir; |
270 | } | |
271 | ||
272 | raw_ostream &OS = outs(); | |
273 | for (int i = 1; i != argc; ++i) { | |
274 | StringRef Arg = argv[i]; | |
275 | ||
276 | if (Arg.startswith("-")) { | |
277 | HasAnyOption = true; | |
278 | if (Arg == "--version") { | |
279 | OS << PACKAGE_VERSION << '\n'; | |
280 | } else if (Arg == "--prefix") { | |
281 | OS << ActivePrefix << '\n'; | |
282 | } else if (Arg == "--bindir") { | |
283 | OS << ActiveBinDir << '\n'; | |
284 | } else if (Arg == "--includedir") { | |
285 | OS << ActiveIncludeDir << '\n'; | |
286 | } else if (Arg == "--libdir") { | |
287 | OS << ActiveLibDir << '\n'; | |
288 | } else if (Arg == "--cppflags") { | |
289 | OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << '\n'; | |
290 | } else if (Arg == "--cflags") { | |
291 | OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << '\n'; | |
292 | } else if (Arg == "--cxxflags") { | |
293 | OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n'; | |
294 | } else if (Arg == "--ldflags") { | |
1a4d82fc JJ |
295 | OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n'; |
296 | } else if (Arg == "--system-libs") { | |
297 | PrintSystemLibs = true; | |
223e47cc LB |
298 | } else if (Arg == "--libs") { |
299 | PrintLibs = true; | |
300 | } else if (Arg == "--libnames") { | |
301 | PrintLibNames = true; | |
302 | } else if (Arg == "--libfiles") { | |
303 | PrintLibFiles = true; | |
304 | } else if (Arg == "--components") { | |
305 | for (unsigned j = 0; j != array_lengthof(AvailableComponents); ++j) { | |
306 | // Only include non-installed components when in a development tree. | |
307 | if (!AvailableComponents[j].IsInstalled && !IsInDevelopmentTree) | |
308 | continue; | |
309 | ||
310 | OS << ' '; | |
311 | OS << AvailableComponents[j].Name; | |
312 | } | |
313 | OS << '\n'; | |
314 | } else if (Arg == "--targets-built") { | |
315 | OS << LLVM_TARGETS_BUILT << '\n'; | |
316 | } else if (Arg == "--host-target") { | |
1a4d82fc | 317 | OS << Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE) << '\n'; |
223e47cc | 318 | } else if (Arg == "--build-mode") { |
1a4d82fc JJ |
319 | OS << build_mode << '\n'; |
320 | } else if (Arg == "--assertion-mode") { | |
321 | #if defined(NDEBUG) | |
322 | OS << "OFF\n"; | |
323 | #else | |
324 | OS << "ON\n"; | |
325 | #endif | |
223e47cc | 326 | } else if (Arg == "--obj-root") { |
1a4d82fc | 327 | OS << ActivePrefix << '\n'; |
223e47cc LB |
328 | } else if (Arg == "--src-root") { |
329 | OS << LLVM_SRC_ROOT << '\n'; | |
330 | } else { | |
331 | usage(); | |
332 | } | |
333 | } else { | |
334 | Components.push_back(Arg); | |
335 | } | |
336 | } | |
337 | ||
338 | if (!HasAnyOption) | |
339 | usage(); | |
340 | ||
1a4d82fc | 341 | if (PrintLibs || PrintLibNames || PrintLibFiles || PrintSystemLibs) { |
223e47cc LB |
342 | // If no components were specified, default to "all". |
343 | if (Components.empty()) | |
344 | Components.push_back("all"); | |
345 | ||
346 | // Construct the list of all the required libraries. | |
347 | std::vector<StringRef> RequiredLibs; | |
348 | ComputeLibsForComponents(Components, RequiredLibs, | |
349 | /*IncludeNonInstalled=*/IsInDevelopmentTree); | |
350 | ||
1a4d82fc JJ |
351 | if (PrintLibs || PrintLibNames || PrintLibFiles) { |
352 | for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) { | |
353 | StringRef Lib = RequiredLibs[i]; | |
354 | if (i) | |
355 | OS << ' '; | |
223e47cc | 356 | |
1a4d82fc JJ |
357 | if (PrintLibNames) { |
358 | OS << Lib; | |
359 | } else if (PrintLibFiles) { | |
360 | OS << ActiveLibDir << '/' << Lib; | |
361 | } else if (PrintLibs) { | |
362 | // If this is a typical library name, include it using -l. | |
363 | if (Lib.startswith("lib") && Lib.endswith(".a")) { | |
364 | OS << "-l" << Lib.slice(3, Lib.size()-2); | |
365 | continue; | |
366 | } | |
367 | ||
368 | // Otherwise, print the full path. | |
369 | OS << ActiveLibDir << '/' << Lib; | |
370 | } | |
223e47cc | 371 | } |
1a4d82fc | 372 | OS << '\n'; |
223e47cc | 373 | } |
1a4d82fc JJ |
374 | |
375 | // Print SYSTEM_LIBS after --libs. | |
376 | // FIXME: Each LLVM component may have its dependent system libs. | |
377 | if (PrintSystemLibs) | |
378 | OS << LLVM_SYSTEM_LIBS << '\n'; | |
223e47cc LB |
379 | } else if (!Components.empty()) { |
380 | errs() << "llvm-config: error: components given, but unused\n\n"; | |
381 | usage(); | |
382 | } | |
383 | ||
384 | return 0; | |
385 | } |