From 787003a65579f878080eb0a1899e223681159f2c Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Mon, 1 Apr 2024 15:22:19 +0300
Subject: [PATCH 36/36] Meson: Add 'appimage' option

See RM #393

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 doc/INSTALL.meson                     |  5 ++++
 gen_headers/meson_freeciv_config.h.in |  3 +++
 meson.build                           |  4 ++++
 meson_options.txt                     |  5 ++++
 utility/shared.c                      | 34 +++++++++++++++++++++++----
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/doc/INSTALL.meson b/doc/INSTALL.meson
index 43b31428e8..86878b333a 100644
--- a/doc/INSTALL.meson
+++ b/doc/INSTALL.meson
@@ -168,6 +168,11 @@ server ('disabled'/'enabled'/'freeciv-web'):
   means that freeciv-web version will be built instead of
   the regular server.
 
+appimage (boolean):
+  Make build suitable for AppImage packaging. This affects paths from
+  which various resources are looked from, and produces build that
+  doesn't work outside AppImage.
+
 gen-packets-args (array):
   Aditional packet generator arguments passed to common/generate_packets.py.
 
diff --git a/gen_headers/meson_freeciv_config.h.in b/gen_headers/meson_freeciv_config.h.in
index 2a88782f50..421497ed00 100644
--- a/gen_headers/meson_freeciv_config.h.in
+++ b/gen_headers/meson_freeciv_config.h.in
@@ -27,6 +27,9 @@
 /* Is this freeciv-web instead of regular build */
 #mesondefine FREECIV_WEB
 
+/* Is this appimage build instead of regular one */
+#mesondefine FREECIV_APPIMAGE
+
 /* Version tag to follow */
 #mesondefine FOLLOWTAG
 
diff --git a/meson.build b/meson.build
index 82b9d0c2da..3ff040fcac 100644
--- a/meson.build
+++ b/meson.build
@@ -245,6 +245,10 @@ else
   emscripten = false
 endif
 
+if get_option('appimage')
+  pub_conf_data.set('FREECIV_APPIMAGE', 1)
+endif
+
 # From this, at least the _WIN32_WINNT must be set before
 # trying to find the functions.
 if host_system == 'windows'
diff --git a/meson_options.txt b/meson_options.txt
index ee08170649..8fda02ed2d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -73,6 +73,11 @@ option('server',
        value: 'enabled',
        description: 'What kind of server should be build, if any')
 
+option('appimage',
+       type: 'boolean',
+       value: false,
+       description: 'Make a build suitable for AppImage packaging')
+
 option('gen-packets-args',
        type: 'array',
        value: [],
diff --git a/utility/shared.c b/utility/shared.c
index 1dd8eb74eb..c637ae73d3 100644
--- a/utility/shared.c
+++ b/utility/shared.c
@@ -898,14 +898,26 @@ const struct strvec *get_data_dirs(void)
   if (NULL == data_dir_names) {
     const char *path;
 
+#ifdef FREECIV_APPIMAGE
+    char default_data_path[5000];
+
+    fc_snprintf(default_data_path, sizeof(default_data_path),
+                FREECIV_STORAGE_DIR DIR_SEPARATOR DATASUBDIR
+                PATH_SEPARATOR
+                "%s/usr/share/freeciv",
+                getenv("APPDIR"));
+#else  /* FREECIV_APPIMAGE */
+#define default_data_path DEFAULT_DATA_PATH
+#endif /* FREECIV_APPIMAGE */
+
     if ((path = getenv(FREECIV_DATA_PATH)) && '\0' == path[0]) {
       /* TRANS: <FREECIV_DATA_PATH> configuration error */
       log_error(_("\"%s\" is set but empty; using default \"%s\" "
                  "data directories instead."),
-                FREECIV_DATA_PATH, DEFAULT_DATA_PATH);
+                FREECIV_DATA_PATH, default_data_path);
       path = NULL;
     }
-    data_dir_names = base_get_dirs(NULL != path ? path : DEFAULT_DATA_PATH);
+    data_dir_names = base_get_dirs(NULL != path ? path : default_data_path);
     strvec_remove_duplicate(data_dir_names, strcmp); /* Don't set a path both. */
     strvec_iterate(data_dir_names, dirname) {
       log_verbose("Data path component: %s", dirname);
@@ -971,14 +983,28 @@ const struct strvec *get_scenario_dirs(void)
   if (NULL == scenario_dir_names) {
     const char *path;
 
+#ifdef FREECIV_APPIMAGE
+    char default_scenario_path[5000];
+
+    fc_snprintf(default_scenario_path, sizeof(default_scenario_path),
+                FREECIV_STORAGE_DIR DIR_SEPARATOR DATASUBDIR DIR_SEPARATOR "scenarios"
+                PATH_SEPARATOR
+                FREECIV_STORAGE_DIR DIR_SEPARATOR "scenarios"
+                PATH_SEPARATOR
+                "%s/usr/share/freeciv/scenarios",
+                getenv("APPDIR"));
+#else  /* FREECIV_APPIMAGE */
+#define default_scenario_path DEFAULT_SCENARIO_PATH
+#endif /* FREECIV_APPIMAGE */
+
     if ((path = getenv(FREECIV_SCENARIO_PATH)) && '\0' == path[0]) {
       /* TRANS: <FREECIV_SCENARIO_PATH> configuration error */
       log_error( _("\"%s\" is set but empty; using default \"%s\" "
                    "scenario directories instead."),
-                 FREECIV_SCENARIO_PATH, DEFAULT_SCENARIO_PATH);
+                 FREECIV_SCENARIO_PATH, default_scenario_path);
       path = NULL;
     }
-    scenario_dir_names = base_get_dirs(NULL != path ? path : DEFAULT_SCENARIO_PATH);
+    scenario_dir_names = base_get_dirs(NULL != path ? path : default_scenario_path);
     strvec_remove_duplicate(scenario_dir_names, strcmp); /* Don't set a path both. */
     strvec_iterate(scenario_dir_names, dirname) {
       log_verbose("Scenario path component: %s", dirname);
-- 
2.43.0

