diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2019-03-05 02:18:16 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2019-03-05 02:18:16 +0000 |
commit | 6bf3978e9a0c5594b0932a180981e31044f4d446 (patch) | |
tree | 118515f9d897f155420d9c193b37a0813b0e88fb /gnu | |
parent | 1a6a430f4a78b2eda0e0cb88f6e7d1d293f0bfe0 (diff) |
libLLVM in base will be installed as libLLVM.so.major.minor with no
symlink for libLLVM-7.so or libLLVM.so. Adjust llvm-config to cope and
force llvm-config DyLibExists to true.
This is specific to LLVM in base this patch should not be used in ports.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/llvm/tools/llvm-config/llvm-config.cpp | 350 |
1 files changed, 235 insertions, 115 deletions
diff --git a/gnu/llvm/tools/llvm-config/llvm-config.cpp b/gnu/llvm/tools/llvm-config/llvm-config.cpp index 80f627936d0..d3dbd069ae2 100644 --- a/gnu/llvm/tools/llvm-config/llvm-config.cpp +++ b/gnu/llvm/tools/llvm-config/llvm-config.cpp @@ -17,20 +17,21 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Config/llvm-config.h" #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" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <set> -#include <vector> #include <unordered_set> +#include <vector> using namespace llvm; @@ -46,7 +47,23 @@ using namespace llvm; // create entries for pseudo groups like x86 or all-targets. #include "LibraryDependencies.inc" -/// \brief Traverse a single component adding to the topological ordering in +// LinkMode determines what libraries and flags are returned by llvm-config. +enum LinkMode { + // LinkModeAuto will link with the default link mode for the installation, + // which is dependent on the value of LLVM_LINK_LLVM_DYLIB, and fall back + // to the alternative if the required libraries are not available. + LinkModeAuto = 0, + + // LinkModeShared will link with the dynamic component libraries if they + // exist, and return an error otherwise. + LinkModeShared = 1, + + // LinkModeStatic will link with the static component libraries if they + // exist, and return an error otherwise. + LinkModeStatic = 2, +}; + +/// Traverse a single component adding to the topological ordering in /// \arg RequiredLibs. /// /// \param Name - The component to traverse. @@ -56,14 +73,25 @@ using namespace llvm; /// libraries. /// \param GetComponentNames - Get the component names instead of the /// library name. -static void VisitComponent(const std::string& Name, - const StringMap<AvailableComponent*> &ComponentMap, - std::set<AvailableComponent*> &VisitedComponents, +static void VisitComponent(const std::string &Name, + const StringMap<AvailableComponent *> &ComponentMap, + std::set<AvailableComponent *> &VisitedComponents, std::vector<std::string> &RequiredLibs, bool IncludeNonInstalled, bool GetComponentNames, - const std::string *ActiveLibDir, bool *HasMissing) { + const std::function<std::string(const StringRef &)> + *GetComponentLibraryPath, + std::vector<std::string> *Missing, + const std::string &DirSep) { // Lookup the component. AvailableComponent *AC = ComponentMap.lookup(Name); + if (!AC) { + errs() << "Can't find component: '" << Name << "' in the map. Available components are: "; + for (const auto &Component : ComponentMap) { + errs() << "'" << Component.first() << "' "; + } + errs() << "\n"; + report_fatal_error("abort"); + } assert(AC && "Invalid component name!"); // Add to the visited table. @@ -80,7 +108,7 @@ static void VisitComponent(const std::string& Name, for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) { VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents, RequiredLibs, IncludeNonInstalled, GetComponentNames, - ActiveLibDir, HasMissing); + GetComponentLibraryPath, Missing, DirSep); } if (GetComponentNames) { @@ -90,14 +118,19 @@ static void VisitComponent(const std::string& Name, // Add to the required library list. if (AC->Library) { - if (!IncludeNonInstalled && HasMissing && !*HasMissing && ActiveLibDir) { - *HasMissing = !sys::fs::exists(*ActiveLibDir + "/" + AC->Library); + if (Missing && GetComponentLibraryPath) { + std::string path = (*GetComponentLibraryPath)(AC->Library); + if (DirSep == "\\") { + std::replace(path.begin(), path.end(), '/', '\\'); + } + if (!sys::fs::exists(path)) + Missing->push_back(path); } RequiredLibs.push_back(AC->Library); } } -/// \brief Compute the list of required libraries for a given list of +/// 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). /// @@ -105,15 +138,16 @@ static void VisitComponent(const std::string& Name, /// \param IncludeNonInstalled - Whether non-installed components should be /// reported. /// \param GetComponentNames - True if one would prefer the component names. -static std::vector<std::string> -ComputeLibsForComponents(const std::vector<StringRef> &Components, - bool IncludeNonInstalled, bool GetComponentNames, - const std::string *ActiveLibDir, bool *HasMissing) { +static std::vector<std::string> ComputeLibsForComponents( + const std::vector<StringRef> &Components, bool IncludeNonInstalled, + bool GetComponentNames, const std::function<std::string(const StringRef &)> + *GetComponentLibraryPath, + std::vector<std::string> *Missing, const std::string &DirSep) { std::vector<std::string> RequiredLibs; std::set<AvailableComponent *> VisitedComponents; // Build a map of component names to information. - StringMap<AvailableComponent*> ComponentMap; + StringMap<AvailableComponent *> ComponentMap; for (unsigned i = 0; i != array_lengthof(AvailableComponents); ++i) { AvailableComponent *AC = &AvailableComponents[i]; ComponentMap[AC->Name] = AC; @@ -133,7 +167,7 @@ ComputeLibsForComponents(const std::vector<StringRef> &Components, VisitComponent(ComponentLower, ComponentMap, VisitedComponents, RequiredLibs, IncludeNonInstalled, GetComponentNames, - ActiveLibDir, HasMissing); + GetComponentLibraryPath, Missing, DirSep); } // The list is now ordered with leafs first, we want the libraries to printed @@ -163,6 +197,7 @@ Options:\n\ --bindir Directory containing LLVM executables.\n\ --includedir Directory containing LLVM headers.\n\ --libdir Directory containing LLVM libraries.\n\ + --cmakedir Directory containing LLVM cmake modules.\n\ --cppflags C preprocessor flags for files that include LLVM headers.\n\ --cflags C compiler flags for files that include LLVM headers.\n\ --cxxflags C++ compiler flags for files that include LLVM headers.\n\ @@ -176,34 +211,39 @@ Options:\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\ + --build-system Print the build system used to build LLVM (always cmake).\n\ --has-rtti Print whether or not LLVM was built with rtti (YES or NO).\n\ + --has-global-isel Print whether or not LLVM was built with global-isel support (ON or OFF).\n\ --shared-mode Print how the provided components can be collectively linked (`shared` or `static`).\n\ + --link-shared Link the components as shared libraries.\n\ + --link-static Link the component libraries statically.\n\ + --ignore-libllvm Ignore libLLVM and link component libraries instead.\n\ Typical components:\n\ all All LLVM libraries (default).\n\ engine Either a native JIT or a bitcode interpreter.\n"; exit(1); } -/// \brief Compute the path to the main executable. +/// Compute the path to the main executable. 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; + void *P = (void *)(intptr_t)GetExecutablePath; return llvm::sys::fs::getMainExecutable(Argv0, P); } -/// \brief Expand the semi-colon delimited LLVM_DYLIB_COMPONENTS into +/// Expand the semi-colon delimited LLVM_DYLIB_COMPONENTS into /// the full list of components. std::vector<std::string> GetAllDyLibComponents(const bool IsInDevelopmentTree, - const bool GetComponentNames) { + const bool GetComponentNames, + const std::string &DirSep) { std::vector<StringRef> DyLibComponents; StringRef DyLibComponentsStr(LLVM_DYLIB_COMPONENTS); size_t Offset = 0; while (true) { const size_t NextOffset = DyLibComponentsStr.find(';', Offset); - DyLibComponents.push_back(DyLibComponentsStr.substr(Offset, NextOffset)); + DyLibComponents.push_back(DyLibComponentsStr.substr(Offset, NextOffset-Offset)); if (NextOffset == std::string::npos) { break; } @@ -214,7 +254,7 @@ std::vector<std::string> GetAllDyLibComponents(const bool IsInDevelopmentTree, return ComputeLibsForComponents(DyLibComponents, /*IncludeNonInstalled=*/IsInDevelopmentTree, - GetComponentNames, nullptr, nullptr); + GetComponentNames, nullptr, nullptr, DirSep); } int main(int argc, char **argv) { @@ -228,7 +268,7 @@ int main(int argc, char **argv) { // that we can report the correct information when run from a development // tree. bool IsInDevelopmentTree; - enum { MakefileStyle, CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout; + enum { CMakeStyle, CMakeBuildModeStyle } DevelopmentTreeLayout; llvm::SmallString<256> CurrentPath(GetExecutablePath(argv[0])); std::string CurrentExecPrefix; std::string ActiveObjRoot; @@ -243,25 +283,12 @@ int main(int argc, char **argv) { // Create an absolute path, and pop up one directory (we expect to be inside a // bin dir). sys::fs::make_absolute(CurrentPath); - CurrentExecPrefix = sys::path::parent_path( - sys::path::parent_path(CurrentPath)).str(); + CurrentExecPrefix = + sys::path::parent_path(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). - if (sys::fs::equivalent(CurrentExecPrefix, - Twine(LLVM_OBJ_ROOT) + "/" + build_mode)) { - IsInDevelopmentTree = true; - 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 - // always want to provide information for the host triple. - if (sys::path::filename(LLVM_OBJ_ROOT) == "BuildTools") { - ActiveObjRoot = sys::path::parent_path(LLVM_OBJ_ROOT); - } else { - ActiveObjRoot = LLVM_OBJ_ROOT; - } - } else if (sys::fs::equivalent(CurrentExecPrefix, LLVM_OBJ_ROOT)) { + if (sys::fs::equivalent(CurrentExecPrefix, LLVM_OBJ_ROOT)) { IsInDevelopmentTree = true; DevelopmentTreeLayout = CMakeStyle; ActiveObjRoot = LLVM_OBJ_ROOT; @@ -272,12 +299,13 @@ int main(int argc, char **argv) { ActiveObjRoot = LLVM_OBJ_ROOT; } else { IsInDevelopmentTree = false; - DevelopmentTreeLayout = MakefileStyle; // Initialized to avoid warnings. + DevelopmentTreeLayout = CMakeStyle; // Initialized to avoid warnings. } // Compute various directory locations based on the derived location // information. - std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir; + std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir, + ActiveCMakeDir; std::string ActiveIncludeOption; if (IsInDevelopmentTree) { ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include"; @@ -286,32 +314,31 @@ int main(int argc, char **argv) { // CMake organizes the products differently than a normal prefix style // layout. 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; + ActiveCMakeDir = ActiveLibDir + "/cmake/llvm"; break; case CMakeBuildModeStyle: ActivePrefix = ActiveObjRoot; ActiveBinDir = ActiveObjRoot + "/bin/" + build_mode; ActiveLibDir = ActiveObjRoot + "/lib" + LLVM_LIBDIR_SUFFIX + "/" + build_mode; + ActiveCMakeDir = ActiveLibDir + "/cmake/llvm"; break; } // We need to include files from both the source and object trees. - ActiveIncludeOption = ("-I" + ActiveIncludeDir + " " + - "-I" + ActiveObjRoot + "/include"); + ActiveIncludeOption = + ("-I" + ActiveIncludeDir + " " + "-I" + ActiveObjRoot + "/include"); } else { ActivePrefix = CurrentExecPrefix; ActiveIncludeDir = ActivePrefix + "/include"; - ActiveBinDir = ActivePrefix + "/bin"; + SmallString<256> path(StringRef(LLVM_TOOLS_INSTALL_DIR)); + sys::fs::make_absolute(ActivePrefix, path); + ActiveBinDir = path.str(); ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX; + ActiveCMakeDir = ActiveLibDir + "/cmake/llvm"; ActiveIncludeOption = "-I" + ActiveIncludeDir; } @@ -323,50 +350,81 @@ int main(int argc, char **argv) { /// in the first place. This can't be done at configure/build time. StringRef SharedExt, SharedVersionedExt, SharedDir, SharedPrefix, StaticExt, - StaticPrefix, StaticDir = "lib"; - const Triple HostTriple(Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE)); + StaticPrefix, StaticDir = "lib", DirSep = "/"; + const Triple HostTriple(Triple::normalize(LLVM_HOST_TRIPLE)); if (HostTriple.isOSWindows()) { SharedExt = "dll"; - SharedVersionedExt = PACKAGE_VERSION ".dll"; - StaticExt = "a"; + SharedVersionedExt = LLVM_DYLIB_VERSION ".dll"; + if (HostTriple.isOSCygMing()) { + StaticExt = "a"; + StaticPrefix = "lib"; + } else { + StaticExt = "lib"; + DirSep = "\\"; + std::replace(ActiveObjRoot.begin(), ActiveObjRoot.end(), '/', '\\'); + std::replace(ActivePrefix.begin(), ActivePrefix.end(), '/', '\\'); + std::replace(ActiveBinDir.begin(), ActiveBinDir.end(), '/', '\\'); + std::replace(ActiveLibDir.begin(), ActiveLibDir.end(), '/', '\\'); + std::replace(ActiveCMakeDir.begin(), ActiveCMakeDir.end(), '/', '\\'); + std::replace(ActiveIncludeOption.begin(), ActiveIncludeOption.end(), '/', + '\\'); + } SharedDir = ActiveBinDir; StaticDir = ActiveLibDir; - StaticPrefix = SharedPrefix = "lib"; } else if (HostTriple.isOSDarwin()) { SharedExt = "dylib"; - SharedVersionedExt = PACKAGE_VERSION ".dylib"; + SharedVersionedExt = LLVM_DYLIB_VERSION ".dylib"; + StaticExt = "a"; + StaticDir = SharedDir = ActiveLibDir; + StaticPrefix = SharedPrefix = "lib"; + } else if (HostTriple.isOSOpenBSD()) { + SharedExt = "so"; + SharedVersionedExt = ".so" ; StaticExt = "a"; StaticDir = SharedDir = ActiveLibDir; StaticPrefix = SharedPrefix = "lib"; } else { // default to the unix values: SharedExt = "so"; - SharedVersionedExt = PACKAGE_VERSION ".so"; + SharedVersionedExt = LLVM_DYLIB_VERSION ".so"; StaticExt = "a"; StaticDir = SharedDir = ActiveLibDir; StaticPrefix = SharedPrefix = "lib"; } - const bool BuiltDyLib = (std::strcmp(LLVM_ENABLE_DYLIB, "ON") == 0); - - enum { CMake, AutoConf } ConfigTool; - if (std::strcmp(LLVM_BUILD_SYSTEM, "cmake") == 0) { - ConfigTool = CMake; - } else { - ConfigTool = AutoConf; - } + const bool BuiltDyLib = !!LLVM_ENABLE_DYLIB; /// CMake style shared libs, ie each component is in a shared library. - const bool BuiltSharedLibs = - (ConfigTool == CMake && std::strcmp(LLVM_ENABLE_SHARED, "ON") == 0); + const bool BuiltSharedLibs = !!LLVM_ENABLE_SHARED; bool DyLibExists = false; const std::string DyLibName = - (SharedPrefix + "LLVM-" + SharedVersionedExt).str(); + (SharedPrefix + "LLVM" + SharedVersionedExt).str(); + + // If LLVM_LINK_DYLIB is ON, the single shared library will be returned + // for "--libs", etc, if they exist. This behaviour can be overridden with + // --link-static or --link-shared. + bool LinkDyLib = !!LLVM_LINK_DYLIB; if (BuiltDyLib) { - DyLibExists = sys::fs::exists(SharedDir + "/" + DyLibName); + std::string path((SharedDir + DirSep + DyLibName).str()); + if (DirSep == "\\") { + std::replace(path.begin(), path.end(), '/', '\\'); + } + // path does not include major.minor + if (HostTriple.isOSOpenBSD()) { + DyLibExists = true; + } else { + DyLibExists = sys::fs::exists(path); + } + if (!DyLibExists) { + // The shared library does not exist: don't error unless the user + // explicitly passes --link-shared. + LinkDyLib = false; + } } + LinkMode LinkMode = + (LinkDyLib || BuiltSharedLibs) ? LinkModeShared : LinkModeAuto; /// Get the component's library name without the lib prefix and the /// extension. Returns true if Lib is in a recognized format. @@ -392,28 +450,32 @@ int main(int argc, char **argv) { }; /// Maps Unixizms to the host platform. auto GetComponentLibraryFileName = [&](const StringRef &Lib, - const bool ForceShared) { - std::string LibFileName = Lib; - StringRef LibName; - if (GetComponentLibraryNameSlice(Lib, LibName)) { - if (BuiltSharedLibs || ForceShared) { - LibFileName = (SharedPrefix + LibName + "." + SharedExt).str(); + const bool Shared) { + std::string LibFileName; + if (Shared) { + if (Lib == DyLibName) { + // Treat the DyLibName specially. It is not a component library and + // already has the necessary prefix and suffix (e.g. `.so`) added so + // just return it unmodified. + assert(Lib.endswith(SharedExt) && "DyLib is missing suffix"); + LibFileName = Lib; } else { - // default to static - LibFileName = (StaticPrefix + LibName + "." + StaticExt).str(); + LibFileName = (SharedPrefix + Lib + "." + SharedExt).str(); } + } else { + // default to static + LibFileName = (StaticPrefix + Lib + "." + StaticExt).str(); } return LibFileName; }; /// Get the full path for a possibly shared component library. - auto GetComponentLibraryPath = [&](const StringRef &Name, - const bool ForceShared) { - auto LibFileName = GetComponentLibraryFileName(Name, ForceShared); - if (BuiltSharedLibs || ForceShared) { - return (SharedDir + "/" + LibFileName).str(); + auto GetComponentLibraryPath = [&](const StringRef &Name, const bool Shared) { + auto LibFileName = GetComponentLibraryFileName(Name, Shared); + if (Shared) { + return (SharedDir + DirSep + LibFileName).str(); } else { - return (StaticDir + "/" + LibFileName).str(); + return (StaticDir + DirSep + LibFileName).str(); } }; @@ -433,6 +495,8 @@ int main(int argc, char **argv) { OS << ActiveIncludeDir << '\n'; } else if (Arg == "--libdir") { OS << ActiveLibDir << '\n'; + } else if (Arg == "--cmakedir") { + OS << ActiveCMakeDir << '\n'; } else if (Arg == "--cppflags") { OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << '\n'; } else if (Arg == "--cflags") { @@ -440,7 +504,8 @@ int main(int argc, char **argv) { } else if (Arg == "--cxxflags") { OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n'; } else if (Arg == "--ldflags") { - OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n'; + OS << ((HostTriple.isWindowsMSVCEnvironment()) ? "-LIBPATH:" : "-L") + << ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n'; } else if (Arg == "--system-libs") { PrintSystemLibs = true; } else if (Arg == "--libs") { @@ -461,11 +526,15 @@ int main(int argc, char **argv) { Components.push_back(AvailableComponents[j].Name); if (AvailableComponents[j].Library && !IsInDevelopmentTree) { - if (DyLibExists && - !sys::fs::exists(GetComponentLibraryPath( - AvailableComponents[j].Library, false))) { - Components = GetAllDyLibComponents(IsInDevelopmentTree, true); - std::sort(Components.begin(), Components.end()); + std::string path( + GetComponentLibraryPath(AvailableComponents[j].Library, false)); + if (DirSep == "\\") { + std::replace(path.begin(), path.end(), '/', '\\'); + } + if (DyLibExists && !sys::fs::exists(path)) { + Components = + GetAllDyLibComponents(IsInDevelopmentTree, true, DirSep); + llvm::sort(Components.begin(), Components.end()); break; } } @@ -494,13 +563,22 @@ int main(int argc, char **argv) { } else if (Arg == "--build-system") { OS << LLVM_BUILD_SYSTEM << '\n'; } else if (Arg == "--has-rtti") { - OS << LLVM_HAS_RTTI << '\n'; + OS << (LLVM_HAS_RTTI ? "YES" : "NO") << '\n'; + } else if (Arg == "--has-global-isel") { + OS << (LLVM_HAS_GLOBAL_ISEL ? "ON" : "OFF") << '\n'; } else if (Arg == "--shared-mode") { PrintSharedMode = true; } else if (Arg == "--obj-root") { OS << ActivePrefix << '\n'; } else if (Arg == "--src-root") { OS << LLVM_SRC_ROOT << '\n'; + } else if (Arg == "--ignore-libllvm") { + LinkDyLib = false; + LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto; + } else if (Arg == "--link-shared") { + LinkMode = LinkModeShared; + } else if (Arg == "--link-static") { + LinkMode = LinkModeStatic; } else { usage(); } @@ -512,6 +590,11 @@ int main(int argc, char **argv) { if (!HasAnyOption) usage(); + if (LinkMode == LinkModeShared && !DyLibExists && !BuiltSharedLibs) { + WithColor::error(errs(), "llvm-config") << DyLibName << " is missing\n"; + return 1; + } + if (PrintLibs || PrintLibNames || PrintLibFiles || PrintSystemLibs || PrintSharedMode) { @@ -525,16 +608,45 @@ int main(int argc, char **argv) { Components.push_back("all"); // Construct the list of all the required libraries. - bool HasMissing = false; - std::vector<std::string> RequiredLibs = - ComputeLibsForComponents(Components, - /*IncludeNonInstalled=*/IsInDevelopmentTree, - false, &ActiveLibDir, &HasMissing); + std::function<std::string(const StringRef &)> + GetComponentLibraryPathFunction = [&](const StringRef &Name) { + return GetComponentLibraryPath(Name, LinkMode == LinkModeShared); + }; + std::vector<std::string> MissingLibs; + std::vector<std::string> RequiredLibs = ComputeLibsForComponents( + Components, + /*IncludeNonInstalled=*/IsInDevelopmentTree, false, + &GetComponentLibraryPathFunction, &MissingLibs, DirSep); + if (!MissingLibs.empty()) { + switch (LinkMode) { + case LinkModeShared: + if (LinkDyLib && !BuiltSharedLibs) + break; + // Using component shared libraries. + for (auto &Lib : MissingLibs) + WithColor::error(errs(), "llvm-config") << "missing: " << Lib << "\n"; + return 1; + case LinkModeAuto: + if (DyLibExists) { + LinkMode = LinkModeShared; + break; + } + WithColor::error(errs(), "llvm-config") + << "component libraries and shared library\n\n"; + LLVM_FALLTHROUGH; + case LinkModeStatic: + for (auto &Lib : MissingLibs) + WithColor::error(errs(), "llvm-config") << "missing: " << Lib << "\n"; + return 1; + } + } else if (LinkMode == LinkModeAuto) { + LinkMode = LinkModeStatic; + } if (PrintSharedMode) { std::unordered_set<std::string> FullDyLibComponents; std::vector<std::string> DyLibComponents = - GetAllDyLibComponents(IsInDevelopmentTree, false); + GetAllDyLibComponents(IsInDevelopmentTree, false, DirSep); for (auto &Component : DyLibComponents) { FullDyLibComponents.insert(Component); @@ -549,7 +661,7 @@ int main(int argc, char **argv) { } FullDyLibComponents.clear(); - if (HasMissing && DyLibExists) { + if (LinkMode == LinkModeShared) { OS << "shared\n"; return 0; } else { @@ -560,36 +672,39 @@ int main(int argc, char **argv) { if (PrintLibs || PrintLibNames || PrintLibFiles) { - auto PrintForLib = [&](const StringRef &Lib, const bool ForceShared) { + auto PrintForLib = [&](const StringRef &Lib) { + const bool Shared = LinkMode == LinkModeShared; if (PrintLibNames) { - OS << GetComponentLibraryFileName(Lib, ForceShared); + OS << GetComponentLibraryFileName(Lib, Shared); } else if (PrintLibFiles) { - OS << GetComponentLibraryPath(Lib, ForceShared); + OS << GetComponentLibraryPath(Lib, Shared); } else if (PrintLibs) { - // If this is a typical library name, include it using -l. - StringRef LibName; - if (Lib.startswith("lib")) { + // On Windows, output full path to library without parameters. + // Elsewhere, if this is a typical library name, include it using -l. + if (HostTriple.isWindowsMSVCEnvironment()) { + OS << GetComponentLibraryPath(Lib, Shared); + } else { + StringRef LibName; if (GetComponentLibraryNameSlice(Lib, LibName)) { + // Extract library name (remove prefix and suffix). OS << "-l" << LibName; } else { - OS << "-l:" << GetComponentLibraryFileName(Lib, ForceShared); + // Lib is already a library name without prefix and suffix. + OS << "-l" << Lib; } - } else { - // Otherwise, print the full path. - OS << GetComponentLibraryPath(Lib, ForceShared); } } }; - if (HasMissing && DyLibExists) { - PrintForLib(DyLibName, true); + if (LinkMode == LinkModeShared && LinkDyLib) { + PrintForLib(DyLibName); } else { for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) { auto Lib = RequiredLibs[i]; if (i) OS << ' '; - PrintForLib(Lib, false); + PrintForLib(Lib); } } OS << '\n'; @@ -597,10 +712,15 @@ int main(int argc, char **argv) { // Print SYSTEM_LIBS after --libs. // FIXME: Each LLVM component may have its dependent system libs. - if (PrintSystemLibs) - OS << LLVM_SYSTEM_LIBS << '\n'; + if (PrintSystemLibs) { + // Output system libraries only if linking against a static + // library (since the shared library links to all system libs + // already) + OS << (LinkMode == LinkModeStatic ? LLVM_SYSTEM_LIBS : "") << '\n'; + } } else if (!Components.empty()) { - errs() << "llvm-config: error: components given, but unused\n\n"; + WithColor::error(errs(), "llvm-config") + << "components given, but unused\n\n"; usage(); } |