示例#1
0
文件: Utils.cpp 项目: fredroy/sofa
static std::string computeExecutablePath()
{
    std::string path = "";

#if defined(WIN32)
    std::vector<TCHAR> lpFilename(MAX_PATH);
    int ret = GetModuleFileName(NULL, /* NULL --> executable of the current process */
        &lpFilename[0],
        MAX_PATH);
    if (ret == 0 || ret == MAX_PATH) {
        msg_error("Utils::computeExecutablePath()") << Utils::GetLastError();
    } else {
        path = Utils::narrowString(std::wstring(&lpFilename[0]));
    }

#elif defined(__APPLE__)
    std::vector<char> buffer(PATH_MAX);
    std::vector<char> real_path(PATH_MAX);
    uint32_t size = buffer.size();
    if (_NSGetExecutablePath(&buffer[0], &size) != 0) {
        msg_error("Utils::computeExecutablePath()") << "_NSGetExecutablePath() failed";
    }
    if (realpath(&buffer[0], &real_path[0]) == 0) {
        msg_error("Utils::computeExecutablePath()") << "realpath() failed";
    }
    path = std::string(&real_path[0]);

#else  // Linux
    std::vector<char> buffer(PATH_MAX);
    if (readlink("/proc/self/exe", &buffer[0], buffer.size()) == -1) {
        int error = errno;
        msg_error("Utils::computeExecutablePath()") << strerror(error);
    } else {
        path = std::string(&buffer[0]);
    }
#endif

    return FileSystem::cleanPath(path);
}
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<imageCount; ++i) {
		const char *imageName = _dyld_get_image_name(i);
		if (boost::ends_with(imageName, "libmitsuba-core.dylib")) {
			basePath = fs::canonical(imageName).parent_path().parent_path().parent_path();
			break;
		}
	}
	MTS_AUTORELEASE_END()
	if (basePath.empty())
		Log(EError, "Could not detect the executable path!");
#elif defined(__WINDOWS__)
	std::vector<WCHAR> 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<LPCWSTR>(&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<DWORD>(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());
}