+ /// We only use `shared library` mode in cases where the static library form
+ /// of the components provided are not available; note however that this is
+ /// skipped if we're run from within the build dir. However, once installed,
+ /// we still need to provide correct output when the static archives are
+ /// removed or, as in the case of CMake's `BUILD_SHARED_LIBS`, never present
+ /// 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));
+ if (HostTriple.isOSWindows()) {
+ SharedExt = "dll";
+ SharedVersionedExt = PACKAGE_VERSION ".dll";
+ StaticExt = "a";
+ SharedDir = ActiveBinDir;
+ StaticDir = ActiveLibDir;
+ StaticPrefix = SharedPrefix = "lib";
+ } else if (HostTriple.isOSDarwin()) {
+ SharedExt = "dylib";
+ SharedVersionedExt = PACKAGE_VERSION ".dylib";
+ StaticExt = "a";
+ StaticDir = SharedDir = ActiveLibDir;
+ StaticPrefix = SharedPrefix = "lib";
+ } else {
+ // default to the unix values:
+ SharedExt = "so";
+ SharedVersionedExt = PACKAGE_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;
+ }
+
+ /// CMake style shared libs, ie each component is in a shared library.
+ const bool BuiltSharedLibs =
+ (ConfigTool == CMake && std::strcmp(LLVM_ENABLE_SHARED, "ON") == 0);
+
+ bool DyLibExists = false;
+ const std::string DyLibName =
+ (SharedPrefix + "LLVM-" + SharedVersionedExt).str();
+
+ if (BuiltDyLib) {
+ DyLibExists = sys::fs::exists(SharedDir + "/" + DyLibName);
+ }
+
+ /// Get the component's library name without the lib prefix and the
+ /// extension. Returns true if Lib is in a recognized format.
+ auto GetComponentLibraryNameSlice = [&](const StringRef &Lib,
+ StringRef &Out) {
+ if (Lib.startswith("lib")) {
+ unsigned FromEnd;
+ if (Lib.endswith(StaticExt)) {
+ FromEnd = StaticExt.size() + 1;
+ } else if (Lib.endswith(SharedExt)) {
+ FromEnd = SharedExt.size() + 1;
+ } else {
+ FromEnd = 0;
+ }
+
+ if (FromEnd != 0) {
+ Out = Lib.slice(3, Lib.size() - FromEnd);
+ return true;
+ }
+ }
+
+ return false;
+ };
+ /// 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();
+ }
+ }
+
+ 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();
+ } else {
+ return (StaticDir + "/" + LibFileName).str();
+ }
+ };
+