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,5 @@ #define LLVM_LIBDIR_SUFFIX "@LLVM_LIBDIR_SUFFIX@" #define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@" #define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@" +#define LLVM_ENABLE_SHARED "@LLVM_ENABLE_SHARED@" +#define LLVM_BUILT_WITH_CMAKE "@LLVM_BUILT_WITH_CMAKE@" Index: tools/llvm-config/CMakeLists.txt =================================================================== --- tools/llvm-config/CMakeLists.txt +++ tools/llvm-config/CMakeLists.txt @@ -28,6 +28,12 @@ set(LLVM_LDFLAGS "${CMAKE_CXX_LINK_FLAGS}") set(LLVM_BUILDMODE ${CMAKE_BUILD_TYPE}) set(LLVM_SYSTEM_LIBS ${SYSTEM_LIBS}) +if(LLVM_BUILD_LLVM_DYLIB) + set(LLVM_ENABLE_SHARED ON) +else() + set(LLVM_ENABLE_SHARED OFF) +endif() +set(LLVM_BUILT_WITH_CMAKE ON) string(REPLACE ";" " " LLVM_TARGETS_BUILT "${LLVM_TARGETS_TO_BUILD}") configure_file(${BUILDVARIABLES_SRCPATH} ${BUILDVARIABLES_OBJPATH} @ONLY) Index: tools/llvm-config/Makefile =================================================================== --- tools/llvm-config/Makefile +++ tools/llvm-config/Makefile @@ -65,6 +65,11 @@ >> temp.sed $(Verb) $(ECHO) 's/@LLVM_TARGETS_BUILT@/$(subst /,\/,$(TARGETS_TO_BUILD))/' \ >> temp.sed + $(if $(filter-out $(ENABLE_SHARED),0),\ + $(Verb) $(ECHO) 's/@LLVM_ENABLE_SHARED@/ON/',\ + $(Verb) $(ECHO) 's/@LLVM_ENABLE_SHARED@/OFF/') \ + >> temp.sed + $(Verb) $(ECHO) 's/@LLVM_BUILT_WITH_CMAKE@/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,63 @@ // 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 (via `--enable-shared` or + // `LLVM_BUILD_LLVM_DYLIB`) 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' or 'libLLVM.so.3.7.0svn' 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 recommend 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(LLVM_ENABLE_SHARED, "ON") == 0); + if(BuiltWithSharedLib && HasMissing) { + std::string SharedExt; std::string SharedDir; std::string Prefix; + { + const Triple HostTriple(Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE)); + if (HostTriple.isOSWindows() || HostTriple.isOSCygMing()) { + SharedExt = "dll"; + SharedDir = ActiveBinDir; + Prefix = ""; + } else if (HostTriple.isOSDarwin()) { + SharedExt = "dylib"; + SharedDir = ActiveLibDir; + Prefix = "lib"; + } else { + // default to linux' ext: + SharedExt = "so"; + SharedDir = ActiveLibDir; + Prefix = "lib"; + } + } + std::string SharedLibName; + if(std::strcmp(LLVM_BUILT_WITH_CMAKE, "ON") == 0) { + SharedLibName = Prefix + "LLVM." + SharedExt + "." PACKAGE_VERSION; + } else { + SharedLibName = Prefix + "LLVM-" PACKAGE_VERSION "." + SharedExt; + } + + const std::string SharedLibPath = SharedDir + "/" + SharedLibName; + if (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 +423,27 @@ 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(".so." PACKAGE_VERSION)) { + FromEnd = 4 + std::strlen(PACKAGE_VERSION); + } else if (Lib.endswith(".dylib")) { + FromEnd = 6; + } else if (Lib.endswith(".dylib." PACKAGE_VERSION)) { + FromEnd = 7 + std::strlen(PACKAGE_VERSION); + } else { + FromEnd = 0; + } + + if (FromEnd != 0) { + OS << "-l" << Lib.slice(3, Lib.size() - FromEnd); + } else { + OS << "-l:" << Lib; + } continue; }