diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
| commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
| tree | 4def12e759965de927d963ac65840d663ef9d1ea /tools/llvm-config | |
| parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
Diffstat (limited to 'tools/llvm-config')
| -rw-r--r-- | tools/llvm-config/BuildVariables.inc.in | 3 | ||||
| -rw-r--r-- | tools/llvm-config/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | tools/llvm-config/Makefile | 95 | ||||
| -rw-r--r-- | tools/llvm-config/llvm-config.cpp | 287 |
4 files changed, 200 insertions, 199 deletions
diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in index 345f47e91b4a3..709ea35044c6a 100644 --- a/tools/llvm-config/BuildVariables.inc.in +++ b/tools/llvm-config/BuildVariables.inc.in @@ -29,5 +29,8 @@ #define LLVM_BUILD_SYSTEM "@LLVM_BUILD_SYSTEM@" #define LLVM_HAS_RTTI "@LLVM_HAS_RTTI@" #define LLVM_ENABLE_DYLIB "@LLVM_BUILD_LLVM_DYLIB@" +#define LLVM_LINK_DYLIB "@LLVM_LINK_LLVM_DYLIB@" #define LLVM_ENABLE_SHARED "@LLVM_ENABLE_SHARED@" #define LLVM_DYLIB_COMPONENTS "@LLVM_DYLIB_COMPONENTS@" +#define LLVM_DYLIB_VERSION "@LLVM_DYLIB_VERSION@" +#define LLVM_HAS_GLOBAL_ISEL "@LLVM_HAS_GLOBAL_ISEL@" diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt index 83794bb3fddd6..d45877135ba2a 100644 --- a/tools/llvm-config/CMakeLists.txt +++ b/tools/llvm-config/CMakeLists.txt @@ -11,7 +11,17 @@ add_llvm_tool(llvm-config # Compute the substitution values for various items. get_property(LLVM_SYSTEM_LIBS_LIST TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS) foreach(l ${LLVM_SYSTEM_LIBS_LIST}) - set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}") + if(MSVC) + set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}.lib") + else() + if (l MATCHES "^-") + # If it's an option, pass it without changes. + set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}") + else() + # Otherwise assume it's a library name we need to link with. + set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}") + endif() + endif() endforeach() string(REPLACE ";" " " SYSTEM_LIBS "${SYSTEM_LIBS}") @@ -26,6 +36,8 @@ set(LLVM_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} set(LLVM_CXXFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${COMPILE_FLAGS} ${LLVM_DEFINITIONS}") set(LLVM_BUILD_SYSTEM cmake) set(LLVM_HAS_RTTI ${LLVM_CONFIG_HAS_RTTI}) +set(LLVM_DYLIB_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX}") +set(LLVM_HAS_GLOBAL_ISEL "${LLVM_BUILD_GLOBAL_ISEL}") # Use the C++ link flags, since they should be a superset of C link flags. set(LLVM_LDFLAGS "${CMAKE_CXX_LINK_FLAGS}") diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile deleted file mode 100644 index d2fe2cfa34aad..0000000000000 --- a/tools/llvm-config/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -##===- tools/llvm-config/Makefile---------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL := ../.. -TOOLNAME := llvm-config -USEDLIBS := LLVMSupport.a - -# We generate sources in the build directory, make sure it is in the include -# paths. -INCLUDE_BUILD_DIR := 1 - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS := 1 - -# Note that we have to use lazy expansion here. -BUILDVARIABLES_SRCPATH = $(PROJ_SRC_ROOT)/tools/$(TOOLNAME)/BuildVariables.inc.in -BUILDVARIABLES_OBJPATH = $(ObjDir)/BuildVariables.inc -BUILT_SOURCES = $(BUILDVARIABLES_OBJPATH) - -include $(LEVEL)/Makefile.common - -# Combine preprocessor flags (except for -I) and CXX flags. -SUB_CPPFLAGS := ${CPP.BaseFlags} -SUB_CFLAGS := ${CPP.BaseFlags} ${C.Flags} -SUB_CXXFLAGS := ${CPP.BaseFlags} ${CXX.Flags} - -# Override LIBS with TARGET's LIBS for cross compilation. -# FIXME: Host's llvm-config is not generated. It's for target's. -ifneq ($(TARGET_LIBS), ) - LLVM_SYSTEM_LIBS := $(TARGET_LIBS) -else - LLVM_SYSTEM_LIBS := $(LIBS) -endif - -ifneq ($(REQUIRES_RTTI), 1) - LLVM_HAS_RTTI := NO -else - LLVM_HAS_RTTI := YES -endif - -# This is blank for now. We need to be careful about adding stuff here: -# LDFLAGS tend not to be portable, and we don't currently require the -# user to use libtool when linking against LLVM. -SUB_LDFLAGS := - -$(ObjDir)/BuildVariables.inc: $(BUILDVARIABLES_SRCPATH) Makefile $(ObjDir)/.dir - $(Echo) "Building llvm-config BuildVariables.inc file." - $(Verb) $(ECHO) 's/@LLVM_SRC_ROOT@/$(subst /,\/,$(LLVM_SRC_ROOT))/' \ - > temp.sed - $(Verb) $(ECHO) 's/@LLVM_OBJ_ROOT@/$(subst /,\/,$(LLVM_OBJ_ROOT))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_LIBDIR_SUFFIX@//' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_SYSTEM_LIBS@/$(subst /,\/,$(LLVM_SYSTEM_LIBS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_TARGETS_BUILT@/$(subst /,\/,$(TARGETS_TO_BUILD))/' \ - >> temp.sed - $(if $(filter-out $(ENABLE_SHARED),0),\ - $(Verb) $(ECHO) 's/@LLVM_BUILD_LLVM_DYLIB@/ON/',\ - $(Verb) $(ECHO) 's/@LLVM_BUILD_LLVM_DYLIB@/OFF/') \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_ENABLE_SHARED@/OFF/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_DYLIB_COMPONENTS@/all/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_BUILD_SYSTEM@/autoconf/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_HAS_RTTI@/$(LLVM_HAS_RTTI)/' \ - >> temp.sed - $(Verb) $(SED) -f temp.sed < $< > $@ - $(Verb) $(RM) temp.sed - -# When cross-compiling, install a version of llvm-config that runs on the host. -ifeq ($(LLVM_CROSS_COMPILING),1) -install:: $(DESTDIR)$(PROJ_bindir) - $(Echo) Installing llvm-config-host - $(Verb) $(ProgInstall) $(BuildLLVMToolDir)/llvm-config \ - $(DESTDIR)$(PROJ_bindir)/$(program_prefix)llvm-config-host -endif diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp index 80f627936d0cf..94d426be3613e 100644 --- a/tools/llvm-config/llvm-config.cpp +++ b/tools/llvm-config/llvm-config.cpp @@ -29,8 +29,8 @@ #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <set> -#include <vector> #include <unordered_set> +#include <vector> using namespace llvm; @@ -46,6 +46,22 @@ using namespace llvm; // create entries for pseudo groups like x86 or all-targets. #include "LibraryDependencies.inc" +// 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, +}; + /// \brief Traverse a single component adding to the topological ordering in /// \arg RequiredLibs. /// @@ -56,14 +72,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 +107,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,8 +117,13 @@ 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); } @@ -105,15 +137,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 +166,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 @@ -176,9 +209,12 @@ 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 (YES or NO).\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\ Typical components:\n\ all All LLVM libraries (default).\n\ engine Either a native JIT or a bitcode interpreter.\n"; @@ -189,14 +225,15 @@ Typical components:\n\ 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 /// 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); @@ -214,7 +251,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 +265,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 +280,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,7 +296,7 @@ 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 @@ -286,12 +310,6 @@ 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; @@ -305,8 +323,8 @@ int main(int argc, char **argv) { } // 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"; @@ -323,25 +341,36 @@ 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(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 { // default to the unix values: SharedExt = "so"; - SharedVersionedExt = PACKAGE_VERSION ".so"; + SharedVersionedExt = LLVM_DYLIB_VERSION ".so"; StaticExt = "a"; StaticDir = SharedDir = ActiveLibDir; StaticPrefix = SharedPrefix = "lib"; @@ -349,24 +378,32 @@ int main(int argc, char **argv) { 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; - } - /// 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 = std::strcmp(LLVM_ENABLE_SHARED, "ON") == 0; 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 = (std::strcmp(LLVM_LINK_DYLIB, "ON") == 0); if (BuiltDyLib) { - DyLibExists = sys::fs::exists(SharedDir + "/" + DyLibName); + std::string path((SharedDir + DirSep + DyLibName).str()); + if (DirSep == "\\") { + std::replace(path.begin(), path.end(), '/', '\\'); + } + 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 +429,24 @@ 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(); - } else { - // default to static - LibFileName = (StaticPrefix + LibName + "." + StaticExt).str(); - } + const bool Shared) { + std::string LibFileName; + if (Shared) { + 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(); } }; @@ -440,7 +473,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,10 +495,14 @@ 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::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); std::sort(Components.begin(), Components.end()); break; } @@ -495,12 +533,18 @@ int main(int argc, char **argv) { OS << LLVM_BUILD_SYSTEM << '\n'; } else if (Arg == "--has-rtti") { OS << LLVM_HAS_RTTI << '\n'; + } else if (Arg == "--has-global-isel") { + OS << LLVM_HAS_GLOBAL_ISEL << '\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 == "--link-shared") { + LinkMode = LinkModeShared; + } else if (Arg == "--link-static") { + LinkMode = LinkModeStatic; } else { usage(); } @@ -512,6 +556,11 @@ int main(int argc, char **argv) { if (!HasAnyOption) usage(); + if (LinkMode == LinkModeShared && !DyLibExists && !BuiltSharedLibs) { + errs() << "llvm-config: error: " << DyLibName << " is missing\n"; + return 1; + } + if (PrintLibs || PrintLibNames || PrintLibFiles || PrintSystemLibs || PrintSharedMode) { @@ -525,16 +574,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 (DyLibExists && !BuiltSharedLibs) + break; + // Using component shared libraries. + for (auto &Lib : MissingLibs) + errs() << "llvm-config: error: missing: " << Lib << "\n"; + return 1; + case LinkModeAuto: + if (DyLibExists) { + LinkMode = LinkModeShared; + break; + } + errs() + << "llvm-config: error: component libraries and shared library\n\n"; + // fall through + case LinkModeStatic: + for (auto &Lib : MissingLibs) + errs() << "llvm-config: error: 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 +627,7 @@ int main(int argc, char **argv) { } FullDyLibComponents.clear(); - if (HasMissing && DyLibExists) { + if (LinkMode == LinkModeShared) { OS << "shared\n"; return 0; } else { @@ -560,36 +638,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 && !BuiltSharedLibs) { + 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'; |
