Automatically handle running from source/build directory and from package, using whereami library; this should fix not being able to run the application from non-standard build directories.

This commit is contained in:
Alexander Shaduri
2022-01-15 14:35:06 +04:00
parent 0ca482bc5d
commit ad796dad9e
3 changed files with 44 additions and 16 deletions
+22 -16
View File
@@ -431,6 +431,8 @@ bool app_init_and_loop(int& argc, char**& argv)
debug_out_info("app", "Current C locale: " << hz::locale_c_get() << "\n");
debug_out_info("app", "Current C++ locale: " << hz::locale_cpp_get<std::string>() << "\n");
debug_out_info("app", "Current working directory: " << Glib::get_current_dir() << "\n");
#ifdef _WIN32
// Now that all program-specific locale setup has been performed,
@@ -443,24 +445,28 @@ bool app_init_and_loop(int& argc, char**& argv)
// This shows up in About dialog gtk.
Glib::set_application_name(_("GSmartControl"));
// Check whether we're running from build directory, or it's a packaged program.
auto application_dir = hz::fs_get_application_dir();
debug_out_info("app", "Application directory: " << application_dir << "\n");
bool is_from_source = !application_dir.empty() && hz::fs::exists((application_dir / "src")); // this covers standard cmake builds, but not VS.
// Add data file search paths
#ifdef _WIN32
hz::data_file_add_search_directory("icons", hz::fs::u8path(".")); // current dir, since shortcuts also use this icon.
hz::data_file_add_search_directory("ui", hz::fs::u8path("ui"));
hz::data_file_add_search_directory("doc", hz::fs::u8path("doc"));
#else
hz::data_file_add_search_directory("icons", hz::fs::u8path(PACKAGE_PKGDATA_DIR) / "icons"); // /usr/share/program_name/icons
hz::data_file_add_search_directory("ui", hz::fs::u8path(PACKAGE_PKGDATA_DIR) / "ui"); // /usr/share/program_name/ui
hz::data_file_add_search_directory("doc", hz::fs::u8path(PACKAGE_DOC_DIR)); // /usr/share/doc/[packages/]gsmartcontrol
#endif
// Paths in source tree
#ifdef DEBUG_BUILD
hz::data_file_add_search_directory("icons", hz::fs::u8path(PACKAGE_TOP_SOURCE_DIR) / "data");
hz::data_file_add_search_directory("ui", hz::fs::u8path(PACKAGE_TOP_SOURCE_DIR) / "src/ui");
hz::data_file_add_search_directory("doc", hz::fs::u8path(PACKAGE_TOP_SOURCE_DIR) / "doc");
#endif
if (is_from_source) {
hz::data_file_add_search_directory("icons", hz::fs::u8path(PACKAGE_TOP_SOURCE_DIR) / "data");
hz::data_file_add_search_directory("ui", hz::fs::u8path(PACKAGE_TOP_SOURCE_DIR) / "src/ui");
hz::data_file_add_search_directory("doc", hz::fs::u8path(PACKAGE_TOP_SOURCE_DIR) / "doc");
} else {
#ifdef _WIN32
hz::data_file_add_search_directory("icons", application_dir);
hz::data_file_add_search_directory("ui", application_dir / "ui");
hz::data_file_add_search_directory("doc", application_dir / "doc");
#else
hz::data_file_add_search_directory("icons", hz::fs::u8path(PACKAGE_PKGDATA_DIR) / "icons"); // /usr/share/program_name/icons
hz::data_file_add_search_directory("ui", hz::fs::u8path(PACKAGE_PKGDATA_DIR) / "ui"); // /usr/share/program_name/ui
hz::data_file_add_search_directory("doc", hz::fs::u8path(PACKAGE_DOC_DIR)); // /usr/share/doc/[packages/]gsmartcontrol
#endif
}
#ifdef _WIN32
+1
View File
@@ -36,6 +36,7 @@ target_link_libraries(hz
# app_pcrecpp_interface
app_gettext_interface # format_unit.h uses this
libdebug # debug.h
whereami # whereami.h
std::filesystem # fs_ns.h, linking to stdc++fs / c++fs if needed
)
+21
View File
@@ -20,6 +20,7 @@ Copyright:
#include <stdio.h> // off_t, fileno(), _fileno(), _wfopen()
#include <limits>
#include <array>
#include <vector>
#ifdef _WIN32
#include <io.h> // _waccess*()
@@ -39,6 +40,7 @@ Copyright:
#endif
#include "fs_ns.h"
#include "whereami.h"
/// \def HAVE_POSIX_OFF_T_FUNCS
@@ -419,6 +421,25 @@ inline fs::path fs_get_user_config_dir()
/// Get absolute path of the current executable
inline fs::path fs_get_application_dir()
{
auto path_len = static_cast<std::size_t>(wai_getExecutablePath(nullptr, 0, nullptr));
if (path_len == 0) {
return {};
}
std::vector<char> vpath(path_len + 1);
int dirname_length = 0;
// In Windows the path is in utf-8.
wai_getExecutablePath(vpath.data(), int(path_len), &dirname_length);
return {vpath.begin(), vpath.begin() + dirname_length};
}
/// Check if the existing file can be fopen'ed with "rb", or the directory has read perms.
/// Note: This function should be use only as an utility function (e.g. for GUI notification);
/// other uses are not logically concurrent-safe (and therefore, insecure).