llvm.org GIT mirror llvm / 93083d4
tools/llvm-config: improve shared library support Summary: This is a re-commit of r257003, which was reverted, along with the fixes from http://reviews.llvm.org/D15986. r252532 added support for reporting the monolithic library when LLVM_BUILD_LLVM_DYLIB is used. This would only be done if the individual components were not found, and the dynamic library is found. This diff extends this as follows: - If LLVM_LINK_LLVM_DYLIB is set, then prefer the shared library, even if all component libraries exist. - Two flags, --link-shared and --link-static are introduced to provide explicit guidance. If --link-shared is passed and the shared library does not exist, an error results. Additionally, changed the expected shared library names from (e.g.) LLVM-3.8.0 to LLVM-3.8. The former exists only in an installation (and then only in CMake builds I think?), and not in the build tree; this breaks usage of llvm-config during builds, e.g. by llvm-go. Reviewers: DiamondLovesYou, beanz Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D15986 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258283 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Wilkins 3 years ago
6 changed file(s) with 132 addition(s) and 67 deletion(s). Raw diff Collapse all Expand all
912912 set(cppflags "${cppflags} -I${d}")
913913 endforeach(d)
914914 set(ldflags "${CMAKE_EXE_LINKER_FLAGS}")
915 if (LLVM_LINK_LLVM_DYLIB)
916 set(linkmode "dylib")
917 else()
918 set(linkmode "component-libs")
919 endif()
920915 add_custom_command(OUTPUT ${binpath}
921 COMMAND ${CMAKE_BINARY_DIR}/bin/llvm-go "go=${GO_EXECUTABLE}" "cc=${cc}" "cxx=${cxx}" "cppflags=${cppflags}" "ldflags=${ldflags}" "linkmode=${linkmode}"
916 COMMAND ${CMAKE_BINARY_DIR}/bin/llvm-go "go=${GO_EXECUTABLE}" "cc=${cc}" "cxx=${cxx}" "cppflags=${cppflags}" "ldflags=${ldflags}"
922917 ${ARG_GOFLAGS} build -o ${binpath} ${pkgpath}
923918 DEPENDS llvm-config ${CMAKE_BINARY_DIR}/bin/llvm-go${CMAKE_EXECUTABLE_SUFFIX}
924919 ${llvmlibs} ${ARG_DEPENDS}
2828 #define LLVM_BUILD_SYSTEM "@LLVM_BUILD_SYSTEM@"
2929 #define LLVM_HAS_RTTI "@LLVM_HAS_RTTI@"
3030 #define LLVM_ENABLE_DYLIB "@LLVM_BUILD_LLVM_DYLIB@"
31 #define LLVM_LINK_DYLIB "@LLVM_LINK_LLVM_DYLIB@"
3132 #define LLVM_ENABLE_SHARED "@LLVM_ENABLE_SHARED@"
3233 #define LLVM_DYLIB_COMPONENTS "@LLVM_DYLIB_COMPONENTS@"
34 #define LLVM_DYLIB_VERSION "@LLVM_DYLIB_VERSION@"
2525 set(LLVM_CXXFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${COMPILE_FLAGS} ${LLVM_DEFINITIONS}")
2626 set(LLVM_BUILD_SYSTEM cmake)
2727 set(LLVM_HAS_RTTI ${LLVM_CONFIG_HAS_RTTI})
28 set(LLVM_DYLIB_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX}")
2829
2930 # Use the C++ link flags, since they should be a superset of C link flags.
3031 set(LLVM_LDFLAGS "${CMAKE_CXX_LINK_FLAGS}")
4343 LLVM_HAS_RTTI := YES
4444 endif
4545
46 LLVM_DYLIB_VERSION := $(LLVM_VERSION_MAJOR).$(LLVM_VERSION_MINOR)$(LLVM_VERSION_SUFFIX)
47
4648 # This is blank for now. We need to be careful about adding stuff here:
4749 # LDFLAGS tend not to be portable, and we don't currently require the
4850 # user to use libtool when linking against LLVM.
8284 >> temp.sed
8385 $(Verb) $(ECHO) 's/@LLVM_HAS_RTTI@/$(LLVM_HAS_RTTI)/' \
8486 >> temp.sed
87 $(Verb) $(ECHO) 's/@LLVM_DYLIB_VERSION@/$(LLVM_DYLIB_VERSION)/' \
88 >> temp.sed
8589 $(Verb) $(SED) -f temp.sed < $< > $@
8690 $(Verb) $(RM) temp.sed
8791
2828 #include "llvm/Support/raw_ostream.h"
2929 #include
3030 #include
31 #include
3132 #include
32 #include
3333
3434 using namespace llvm;
3535
4444 // Not all components define a library, we also use "library groups" as a way to
4545 // create entries for pseudo groups like x86 or all-targets.
4646 #include "LibraryDependencies.inc"
47
48 // LinkMode determines what libraries and flags are returned by llvm-config.
49 enum LinkMode {
50 // LinkModeAuto will link with the default link mode for the installation,
51 // which is dependent on the value of LLVM_LINK_LLVM_DYLIB, and fall back
52 // to the alternative if the required libraries are not available.
53 LinkModeAuto = 0,
54
55 // LinkModeShared will link with the dynamic component libraries if they
56 // exist, and return an error otherwise.
57 LinkModeShared = 1,
58
59 // LinkModeStatic will link with the static component libraries if they
60 // exist, and return an error otherwise.
61 LinkModeStatic = 2,
62 };
4763
4864 /// \brief Traverse a single component adding to the topological ordering in
4965 /// \arg RequiredLibs.
5571 /// libraries.
5672 /// \param GetComponentNames - Get the component names instead of the
5773 /// library name.
58 static void VisitComponent(const std::string& Name,
59 const StringMap &ComponentMap,
60 std::set &VisitedComponents,
74 static void VisitComponent(const std::string &Name,
75 const StringMap &ComponentMap,
76 std::set &VisitedComponents,
6177 std::vector &RequiredLibs,
6278 bool IncludeNonInstalled, bool GetComponentNames,
63 const std::string *ActiveLibDir, bool *HasMissing) {
79 const std::function
80 *GetComponentLibraryPath,
81 std::vector *Missing) {
6482 // Lookup the component.
6583 AvailableComponent *AC = ComponentMap.lookup(Name);
6684 assert(AC && "Invalid component name!");
7997 for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) {
8098 VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents,
8199 RequiredLibs, IncludeNonInstalled, GetComponentNames,
82 ActiveLibDir, HasMissing);
100 GetComponentLibraryPath, Missing);
83101 }
84102
85103 if (GetComponentNames) {
89107
90108 // Add to the required library list.
91109 if (AC->Library) {
92 if (!IncludeNonInstalled && HasMissing && !*HasMissing && ActiveLibDir) {
93 *HasMissing = !sys::fs::exists(*ActiveLibDir + "/" + AC->Library);
110 if (Missing && GetComponentLibraryPath) {
111 std::string path = (*GetComponentLibraryPath)(AC->Library);
112 if (!sys::fs::exists(path))
113 Missing->push_back(path);
94114 }
95115 RequiredLibs.push_back(AC->Library);
96116 }
107127 static std::vector
108128 ComputeLibsForComponents(const std::vector &Components,
109129 bool IncludeNonInstalled, bool GetComponentNames,
110 const std::string *ActiveLibDir, bool *HasMissing) {
130 const std::function
131 *GetComponentLibraryPath,
132 std::vector *Missing) {
111133 std::vector RequiredLibs;
112134 std::set VisitedComponents;
113135
114136 // Build a map of component names to information.
115 StringMap*> ComponentMap;
137 StringMap *> ComponentMap;
116138 for (unsigned i = 0; i != array_lengthof(AvailableComponents); ++i) {
117139 AvailableComponent *AC = &AvailableComponents[i];
118140 ComponentMap[AC->Name] = AC;
132154
133155 VisitComponent(ComponentLower, ComponentMap, VisitedComponents,
134156 RequiredLibs, IncludeNonInstalled, GetComponentNames,
135 ActiveLibDir, HasMissing);
157 GetComponentLibraryPath, Missing);
136158 }
137159
138160 // The list is now ordered with leafs first, we want the libraries to printed
178200 --build-system Print the build system used to build LLVM (autoconf or cmake).\n\
179201 --has-rtti Print whether or not LLVM was built with rtti (YES or NO).\n\
180202 --shared-mode Print how the provided components can be collectively linked (`shared` or `static`).\n\
203 --link-shared Link the components as shared libraries.\n\
204 --link-static Link the component libraries statically.\n\
181205 Typical components:\n\
182206 all All LLVM libraries (default).\n\
183207 engine Either a native JIT or a bitcode interpreter.\n";
188212 std::string GetExecutablePath(const char *Argv0) {
189213 // This just needs to be some symbol in the binary; C++ doesn't
190214 // allow taking the address of ::main however.
191 void *P = (void*) (intptr_t) GetExecutablePath;
215 void *P = (void *)(intptr_t)GetExecutablePath;
192216 return llvm::sys::fs::getMainExecutable(Argv0, P);
193217 }
194218
242266 // Create an absolute path, and pop up one directory (we expect to be inside a
243267 // bin dir).
244268 sys::fs::make_absolute(CurrentPath);
245 CurrentExecPrefix = sys::path::parent_path(
246 sys::path::parent_path(CurrentPath)).str();
269 CurrentExecPrefix =
270 sys::path::parent_path(sys::path::parent_path(CurrentPath)).str();
247271
248272 // Check to see if we are inside a development tree by comparing to possible
249273 // locations (prefix style or CMake style).
304328 }
305329
306330 // We need to include files from both the source and object trees.
307 ActiveIncludeOption = ("-I" + ActiveIncludeDir + " " +
308 "-I" + ActiveObjRoot + "/include");
331 ActiveIncludeOption =
332 ("-I" + ActiveIncludeDir + " " + "-I" + ActiveObjRoot + "/include");
309333 } else {
310334 ActivePrefix = CurrentExecPrefix;
311335 ActiveIncludeDir = ActivePrefix + "/include";
322346 /// in the first place. This can't be done at configure/build time.
323347
324348 StringRef SharedExt, SharedVersionedExt, SharedDir, SharedPrefix, StaticExt,
325 StaticPrefix, StaticDir = "lib";
349 StaticPrefix, StaticDir = "lib";
326350 const Triple HostTriple(Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE));
327351 if (HostTriple.isOSWindows()) {
328352 SharedExt = "dll";
329 SharedVersionedExt = PACKAGE_VERSION ".dll";
353 SharedVersionedExt = LLVM_DYLIB_VERSION ".dll";
330354 StaticExt = "a";
331355 SharedDir = ActiveBinDir;
332356 StaticDir = ActiveLibDir;
333357 StaticPrefix = SharedPrefix = "lib";
334358 } else if (HostTriple.isOSDarwin()) {
335359 SharedExt = "dylib";
336 SharedVersionedExt = PACKAGE_VERSION ".dylib";
360 SharedVersionedExt = LLVM_DYLIB_VERSION ".dylib";
337361 StaticExt = "a";
338362 StaticDir = SharedDir = ActiveLibDir;
339363 StaticPrefix = SharedPrefix = "lib";
340364 } else {
341365 // default to the unix values:
342366 SharedExt = "so";
343 SharedVersionedExt = PACKAGE_VERSION ".so";
367 SharedVersionedExt = LLVM_DYLIB_VERSION ".so";
344368 StaticExt = "a";
345369 StaticDir = SharedDir = ActiveLibDir;
346370 StaticPrefix = SharedPrefix = "lib";
361385
362386 bool DyLibExists = false;
363387 const std::string DyLibName =
364 (SharedPrefix + "LLVM-" + SharedVersionedExt).str();
388 (SharedPrefix + "LLVM-" + SharedVersionedExt).str();
389
390 // If LLVM_LINK_DYLIB is ON, the single shared library will be returned
391 // for "--libs", etc, if they exist. This behaviour can be overridden with
392 // --link-static or --link-shared.
393 bool LinkDyLib = (std::strcmp(LLVM_LINK_DYLIB, "ON") == 0);
365394
366395 if (BuiltDyLib) {
367396 DyLibExists = sys::fs::exists(SharedDir + "/" + DyLibName);
368 }
397 if (!DyLibExists) {
398 // The shared library does not exist: don't error unless the user
399 // explicitly passes --link-shared.
400 LinkDyLib = false;
401 }
402 }
403 LinkMode LinkMode =
404 (LinkDyLib || BuiltSharedLibs) ? LinkModeShared : LinkModeAuto;
369405
370406 /// Get the component's library name without the lib prefix and the
371407 /// extension. Returns true if Lib is in a recognized format.
391427 };
392428 /// Maps Unixizms to the host platform.
393429 auto GetComponentLibraryFileName = [&](const StringRef &Lib,
394 const bool ForceShared) {
430 const bool Shared) {
395431 std::string LibFileName = Lib;
396432 StringRef LibName;
397433 if (GetComponentLibraryNameSlice(Lib, LibName)) {
398 if (BuiltSharedLibs || ForceShared) {
434 if (Shared) {
399435 LibFileName = (SharedPrefix + LibName + "." + SharedExt).str();
400436 } else {
401437 // default to static
406442 return LibFileName;
407443 };
408444 /// Get the full path for a possibly shared component library.
409 auto GetComponentLibraryPath = [&](const StringRef &Name,
410 const bool ForceShared) {
411 auto LibFileName = GetComponentLibraryFileName(Name, ForceShared);
412 if (BuiltSharedLibs || ForceShared) {
445 auto GetComponentLibraryPath = [&](const StringRef &Name, const bool Shared) {
446 auto LibFileName = GetComponentLibraryFileName(Name, Shared);
447 if (Shared) {
413448 return (SharedDir + "/" + LibFileName).str();
414449 } else {
415450 return (StaticDir + "/" + LibFileName).str();
500535 OS << ActivePrefix << '\n';
501536 } else if (Arg == "--src-root") {
502537 OS << LLVM_SRC_ROOT << '\n';
538 } else if (Arg == "--link-shared") {
539 LinkMode = LinkModeShared;
540 } else if (Arg == "--link-static") {
541 LinkMode = LinkModeStatic;
503542 } else {
504543 usage();
505544 }
510549
511550 if (!HasAnyOption)
512551 usage();
552
553 if (LinkMode == LinkModeShared && !DyLibExists && !BuiltSharedLibs) {
554 errs() << "llvm-config: error: " << DyLibName << " is missing\n";
555 return 1;
556 }
513557
514558 if (PrintLibs || PrintLibNames || PrintLibFiles || PrintSystemLibs ||
515559 PrintSharedMode) {
524568 Components.push_back("all");
525569
526570 // Construct the list of all the required libraries.
527 bool HasMissing = false;
528 std::vector RequiredLibs =
529 ComputeLibsForComponents(Components,
530 /*IncludeNonInstalled=*/IsInDevelopmentTree,
531 false, &ActiveLibDir, &HasMissing);
571 std::function
572 GetComponentLibraryPathFunction = [&](const StringRef &Name) {
573 return GetComponentLibraryPath(Name, LinkMode == LinkModeShared);
574 };
575 std::vector MissingLibs;
576 std::vector RequiredLibs = ComputeLibsForComponents(
577 Components,
578 /*IncludeNonInstalled=*/IsInDevelopmentTree, false,
579 &GetComponentLibraryPathFunction, &MissingLibs);
580 if (!MissingLibs.empty()) {
581 switch (LinkMode) {
582 case LinkModeShared:
583 if (DyLibExists && !BuiltSharedLibs)
584 break;
585 // Using component shared libraries.
586 for (auto &Lib : MissingLibs)
587 errs() << "llvm-config: error: missing: " << Lib << "\n";
588 return 1;
589 case LinkModeAuto:
590 if (DyLibExists) {
591 LinkMode = LinkModeShared;
592 break;
593 }
594 errs()
595 << "llvm-config: error: component libraries and shared library\n\n";
596 // fall through
597 case LinkModeStatic:
598 for (auto &Lib : MissingLibs)
599 errs() << "llvm-config: error: missing: " << Lib << "\n";
600 return 1;
601 }
602 } else if (LinkMode == LinkModeAuto) {
603 LinkMode = LinkModeStatic;
604 }
532605
533606 if (PrintSharedMode) {
534607 std::unordered_set FullDyLibComponents;
548621 }
549622 FullDyLibComponents.clear();
550623
551 if (HasMissing && DyLibExists) {
624 if (LinkMode == LinkModeShared) {
552625 OS << "shared\n";
553626 return 0;
554627 } else {
559632
560633 if (PrintLibs || PrintLibNames || PrintLibFiles) {
561634
562 auto PrintForLib = [&](const StringRef &Lib, const bool ForceShared) {
635 auto PrintForLib = [&](const StringRef &Lib) {
636 const bool Shared = LinkMode == LinkModeShared;
563637 if (PrintLibNames) {
564 OS << GetComponentLibraryFileName(Lib, ForceShared);
638 OS << GetComponentLibraryFileName(Lib, Shared);
565639 } else if (PrintLibFiles) {
566 OS << GetComponentLibraryPath(Lib, ForceShared);
640 OS << GetComponentLibraryPath(Lib, Shared);
567641 } else if (PrintLibs) {
568642 // If this is a typical library name, include it using -l.
569643 StringRef LibName;
571645 if (GetComponentLibraryNameSlice(Lib, LibName)) {
572646 OS << "-l" << LibName;
573647 } else {
574 OS << "-l:" << GetComponentLibraryFileName(Lib, ForceShared);
648 OS << "-l:" << GetComponentLibraryFileName(Lib, Shared);
575649 }
576650 } else {
577651 // Otherwise, print the full path.
578 OS << GetComponentLibraryPath(Lib, ForceShared);
652 OS << GetComponentLibraryPath(Lib, Shared);
579653 }
580654 }
581655 };
582656
583 if (HasMissing && DyLibExists) {
584 PrintForLib(DyLibName, true);
657 if (LinkMode == LinkModeShared && !BuiltSharedLibs) {
658 PrintForLib(DyLibName);
585659 } else {
586660 for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) {
587661 auto Lib = RequiredLibs[i];
588662 if (i)
589663 OS << ' ';
590664
591 PrintForLib(Lib, false);
665 PrintForLib(Lib);
592666 }
593667 }
594668 OS << '\n';
8787 return outstr
8888 }
8989
90 func llvmFlags(linkmode string) compilerFlags {
91 ldflags := llvmConfig("--ldflags")
92 switch linkmode {
93 case linkmodeComponentLibs:
94 ldflags += " " + llvmConfig(append([]string{"--libs"}, components...)...)
95 case linkmodeDylib:
96 ldflags += " -lLLVM"
97 default:
98 panic("invalid linkmode: " + linkmode)
99 }
100 ldflags += " " + llvmConfig("--system-libs")
90 func llvmFlags() compilerFlags {
91 ldflags := llvmConfig("--ldflags", "--libs", "--system-libs")
10192 if runtime.GOOS != "darwin" {
10293 // OS X doesn't like -rpath with cgo. See:
10394 // https://code.google.com/p/go/issues/detail?id=7293
132123 fmt.Println(strings.Join(components, " "))
133124 }
134125
135 func printConfig(linkmode string) {
136 flags := llvmFlags(linkmode)
126 func printConfig() {
127 flags := llvmFlags()
137128
138129 fmt.Printf(`// +build !byollvm
139130
152143 `, flags.cpp, flags.cxx, flags.ld)
153144 }
154145
155 func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, linkmode string) {
146 func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string) {
156147 args = addTag(args, "byollvm")
157148
158149 srcdir := llvmConfig("--src-root")
181172 newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
182173 newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))
183174
184 flags := llvmFlags(linkmode)
175 flags := llvmFlags()
185176
186177 newenv := []string{
187178 "CC=" + cc,
249240 ldflags := os.Getenv("CGO_LDFLAGS")
250241 gocmd := "go"
251242 llgo := ""
252 linkmode := linkmodeComponentLibs
253243
254244 flags := []struct {
255245 name string
261251 {"llgo", &llgo},
262252 {"cppflags", &cppflags},
263253 {"ldflags", &ldflags},
264 {"linkmode", &linkmode},
265254 }
266255
267256 args := os.Args[1:]
282271
283272 switch args[0] {
284273 case "build", "get", "install", "run", "test":
285 runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, linkmode)
274 runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags)
286275 case "print-components":
287276 printComponents()
288277 case "print-config":
289 printConfig(linkmode)
278 printConfig()
290279 default:
291280 usage()
292281 }