Index: bindings/ocaml/Makefile.ocaml =================================================================== --- bindings/ocaml/Makefile.ocaml +++ bindings/ocaml/Makefile.ocaml @@ -277,6 +277,8 @@ build-deplibs: $(OutputLibs) +$(OcamlDir)/%.so: $(LibDir)/%.so + $(Verb) ln -sf $< $@ $(OcamlDir)/%.a: $(LibDir)/%.a $(Verb) ln -sf $< $@ Index: tools/llvm-config/BuildVariables.inc.in =================================================================== --- tools/llvm-config/BuildVariables.inc.in +++ tools/llvm-config/BuildVariables.inc.in @@ -26,3 +26,4 @@ #define LLVM_LIBDIR_SUFFIX "@LLVM_LIBDIR_SUFFIX@" #define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@" #define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@" +#define BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@" Index: tools/llvm-config/Makefile =================================================================== --- tools/llvm-config/Makefile +++ tools/llvm-config/Makefile @@ -65,6 +65,10 @@ >> temp.sed $(Verb) $(ECHO) 's/@LLVM_TARGETS_BUILT@/$(subst /,\/,$(TARGETS_TO_BUILD))/' \ >> temp.sed + $(if $(filter-out $(ENABLE_SHARED),0),\ + $(Verb) $(ECHO) 's/@BUILD_SHARED_LIBS@/ON/',\ + $(Verb) $(ECHO) 's/@BUILD_SHARED_LIBS@/OFF/') \ + >> temp.sed $(Verb) $(SED) -f temp.sed < $< > $@ $(Verb) $(RM) temp.sed Index: tools/llvm-config/llvm-config.cpp =================================================================== --- tools/llvm-config/llvm-config.cpp +++ tools/llvm-config/llvm-config.cpp @@ -56,7 +56,9 @@ const StringMap &ComponentMap, std::set &VisitedComponents, std::vector &RequiredLibs, - bool IncludeNonInstalled) { + bool IncludeNonInstalled, + std::string &ActiveLibDir, + bool &HasMissing) { // Lookup the component. AvailableComponent *AC = ComponentMap.lookup(Name); assert(AC && "Invalid component name!"); @@ -74,12 +76,17 @@ // Otherwise, visit all the dependencies. for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) { VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents, - RequiredLibs, IncludeNonInstalled); + RequiredLibs, IncludeNonInstalled, ActiveLibDir, + HasMissing); } // Add to the required library list. - if (AC->Library) + if (AC->Library) { + if (!IncludeNonInstalled && !HasMissing) { + HasMissing = !sys::fs::exists(ActiveLibDir + "/" + AC->Library); + } RequiredLibs.push_back(AC->Library); + } } /// \brief Compute the list of required libraries for a given list of @@ -93,7 +100,9 @@ /// reported. static void ComputeLibsForComponents(const std::vector &Components, std::vector &RequiredLibs, - bool IncludeNonInstalled) { + bool IncludeNonInstalled, + std::string &ActiveLibDir, + bool &HasMissing) { std::set VisitedComponents; // Build a map of component names to information. @@ -116,7 +125,8 @@ } VisitComponent(ComponentLower, ComponentMap, VisitedComponents, - RequiredLibs, IncludeNonInstalled); + RequiredLibs, IncludeNonInstalled, ActiveLibDir, + HasMissing); } // The list is now ordered with leafs first, we want the libraries to printed @@ -345,10 +355,47 @@ // Construct the list of all the required libraries. std::vector RequiredLibs; + bool HasMissing = false; ComputeLibsForComponents(Components, RequiredLibs, - /*IncludeNonInstalled=*/IsInDevelopmentTree); + /*IncludeNonInstalled=*/IsInDevelopmentTree, + ActiveLibDir, HasMissing); if (PrintLibs || PrintLibNames || PrintLibFiles) { + // The following only applies if the following is true: + // + // * `llvm-config` isn't inside the build tree (ie it's installed). + // * LLVM is built with shared libs enabled. + // * `llvm-config` finds the platform specific shared library file in the + // 'lib' subfolder within the install root (ie it finds + // 'libLLVM-3.7.0svn.so' on Linux). + // + // If `llvm-config`, when visiting all the components, finds a missing + // archive, it will override the set of `RequiredLibs` to only include + // that shared library. Note that this means that if one has installed + // only select libraries in static form and component X and it's deps are + // among them, `--libname X` will still print static archive names. I + // wouldn't recommending doing that (installing shared library + only some + // static libraries) for obvious reasons, but I thought it should be + // documented nonetheless. + const bool BuiltWithSharedLib = (std::strcmp(BUILD_SHARED_LIBS, "ON") == 0); + std::string SharedLibName = "libLLVM-" PACKAGE_VERSION; + { + const Triple HostTriple(LLVM_DEFAULT_TARGET_TRIPLE); + if (HostTriple.isOSWindows()) { + SharedLibName += ".dll"; + } else if (HostTriple.isOSDarwin()) { + SharedLibName += ".dylib"; + } else { + // default to linux' ext: + SharedLibName += ".so"; + } + } + const std::string SharedLibPath = ActiveLibDir + "/" + SharedLibName; + if (BuiltWithSharedLib && HasMissing && sys::fs::exists(SharedLibPath)) { + RequiredLibs.clear(); + RequiredLibs.push_back(SharedLibName); + } + for (unsigned i = 0, e = RequiredLibs.size(); i != e; ++i) { StringRef Lib = RequiredLibs[i]; if (i) @@ -360,8 +407,23 @@ OS << ActiveLibDir << '/' << Lib; } else if (PrintLibs) { // If this is a typical library name, include it using -l. - if (Lib.startswith("lib") && Lib.endswith(".a")) { - OS << "-l" << Lib.slice(3, Lib.size()-2); + if (Lib.startswith("lib")) { + size_t FromEnd = 0; + if (Lib.endswith(".a")) { + FromEnd = 2; + } else if (Lib.endswith(".so")) { + FromEnd = 3; + } else if (Lib.endswith(".dylib")) { + FromEnd = 6; + } else { + FromEnd = 0; + } + + if (FromEnd != 0) { + OS << "-l" << Lib.slice(3, Lib.size() - FromEnd); + } else { + OS << "-l:" << Lib; + } continue; }