#include #include #if defined(__LINUX__) # if !defined(_GNU_SOURCE) # define _GNU_SOURCE # endif # include #elif defined(__OSX__) # include #elif defined(__WINDOWS__) # include # include #endif MTS_NAMESPACE_BEGIN #if defined(__WINDOWS__) || defined(__LINUX__) namespace { void dummySymbol() { } } #endif FileResolver::FileResolver() { /* Try to detect the base path of the Mitsuba installation */ fs::path basePath; #if defined(__LINUX__) Dl_info info; dladdr((const void *) &dummySymbol, &info); if (info.dli_fname) { /* Try to detect a few default setups */ if (boost::starts_with(info.dli_fname, "/usr/lib") || boost::starts_with(info.dli_fname, "/lib")) { basePath = fs::path("/usr/share/mitsuba"); } else if (boost::starts_with(info.dli_fname, "/usr/local/lib")) { basePath = fs::path("/usr/local/share/mitsuba"); } else { /* This is a locally-compiled repository */ basePath = fs::path(info.dli_fname).parent_path(); } } #elif defined(__OSX__) MTS_AUTORELEASE_BEGIN() uint32_t imageCount = _dyld_image_count(); for (uint32_t i=0; i lpFilename(MAX_PATH); // Module handle to this DLL. If the function fails it sets handle to NULL. // In that case GetModuleFileName will get the name of the executable which // is acceptable soft-failure behavior. HMODULE handle; GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(&dummySymbol), &handle); // Try to get the path with the default MAX_PATH length (260 chars) DWORD nSize = GetModuleFileNameW(handle, &lpFilename[0], MAX_PATH); // Adjust the buffer size in case if was too short while (nSize != 0 && nSize == lpFilename.size()) { lpFilename.resize(nSize * 2); nSize = GetModuleFileNameW(handle, &lpFilename[0], static_cast(lpFilename.size())); } // There is an error if and only if the function returns 0 if (nSize != 0) basePath = fs::path(lpFilename).parent_path(); else Log(EError, "Could not detect the executable path! (%s)", lastErrorText().c_str()); #endif #if BOOST_VERSION >= 104800 m_paths.push_back(fs::canonical(basePath)); #else m_paths.push_back(fs::absolute(basePath)); #endif m_paths.push_back(fs::current_path()); } FileResolver *FileResolver::clone() const { FileResolver *cloned = new FileResolver(); cloned->m_paths = m_paths; return cloned; } void FileResolver::clear() { m_paths.clear(); } void FileResolver::prependPath(const fs::path &path) { for (size_t i=0; ipath().filename().string()) == filename) return it->path(); } } #endif return path; } std::vector FileResolver::resolveAll(const fs::path &path) const { std::vector results; for (size_t i=0; i