void MachOObject::postConstruct() { detectAbsolutePath(); m_header = m_file->header(); for (std::string rpath : m_file->rpaths()) { if (rpath.compare(0, 16, "@executable_path") == 0) { if (isMainModule()) rpath.replace(0, 16, directory()); else { MachOObject* mainModule = MachOMgr::instance()->mainModule(); if (!mainModule) throw std::runtime_error("Cannot resolve @executable_path without a main module"); rpath.replace(0, 16, mainModule->directory()); } } else if (rpath.compare(0, 12, "@loader_path") == 0) { rpath = expandLoaderPath(rpath, this); } m_rpaths.push_back(rpath); } m_bindAllAtLoad = MachOMgr::instance()->bindAtLaunch(); }
std::string DylibSearch::resolve(std::string dylib, MachOObject* requester) { if (dylib.empty()) return std::string(); // expand @rpath, @executable_path and @loader_path if (requester != nullptr && dylib[0] == '@') { if (dylib.compare(0, 16, "@executable_path") == 0) { MachOObject* mainModule = MachOMgr::instance()->mainModule(); if (!mainModule) throw std::runtime_error("Cannot resolve @executable_path without a main module"); dylib.replace(0, 16, mainModule->directory()); } else if (dylib.compare(0, 12, "@loader_path") == 0) { dylib.replace(0, 12, requester->directory()); } else if (dylib.compare(0, 6, "@rpath") == 0) { return resolveViaRpath(dylib, requester); } } // Search in configuration if (const char* aliasTarget = resolveAlias(dylib)) { std::string p; if (!strchr(aliasTarget, '/')) { p = LIB_PATH; p += '/'; p += aliasTarget; // std::cout << p << std::endl; } return p; } // Search in extra paths std::string epath; epath = resolveInPathList(dylib, m_extraPaths); if (!epath.empty()) return epath; // Search in DYLD_LIBRARY_PATH epath = resolveInLdPath(dylib); if (!epath.empty()) return epath; // Try the path as is epath = checkPresence(dylib); if (!epath.empty()) return epath; // If absolute, search in sysroot if (dylib[0] == '/') { const char* prefix = __prefix_get(); if (!MachOMgr::instance()->sysRoot().empty()) { std::vector<std::string> roots = string_explode(MachOMgr::instance()->sysRoot(), ':'); for (const std::string& in_path : roots) { std::string path; if (prefix != nullptr) path = prefix; path += in_path; path += '/'; path += dylib; epath = checkPresence(path); if (!epath.empty()) return epath; } } if (prefix != nullptr) { std::string path = prefix; path += dylib; epath = checkPresence(path); if (!epath.empty()) return epath; } } /*if (MachOMgr::instance()->ignoreMissingDependencies()) { }*/ return std::string(); }
std::string DylibSearch::resolve(std::string dylib, MachOObject* requester) { if (dylib.empty()) return std::string(); // expand @rpath, @executable_path and @loader_path if (requester != nullptr && dylib[0] == '@') { if (dylib.compare(0, 16, "@executable_path") == 0) { MachOObject* mainModule = MachOMgr::instance()->mainModule(); if (!mainModule) throw std::runtime_error("Cannot resolve @executable_path without a main module"); dylib.replace(0, 16, mainModule->directory()); } else if (dylib.compare(0, 12, "@loader_path") == 0) { dylib.replace(0, 12, requester->directory()); } else if (dylib.compare(0, 6, "@rpath") == 0) { return resolveViaRpath(dylib, requester); } } // Search in configuration if (const char* aliasTarget = resolveAlias(dylib)) return aliasTarget; // Search in extra paths std::string epath; epath = resolveInPathList(dylib, m_extraPaths); if (!epath.empty()) return epath; // Search in DYLD_LIBRARY_PATH epath = resolveInLdPath(dylib); if (!epath.empty()) return epath; // Try the path as is epath = checkPresence(dylib); if (!epath.empty()) return epath; // If absolute, search in sysroot if (dylib[0] == '/' && !MachOMgr::instance()->sysRoot().empty()) { std::string path = MachOMgr::instance()->sysRoot(); path += '/'; path += dylib; epath = checkPresence(path); if (!epath.empty()) return epath; } return std::string(); }