cmake: FHS installation
authorThomas Debesse <dev@illwieckz.net>
Sun, 4 Nov 2018 01:01:48 +0000 (02:01 +0100)
committerThomas Debesse <dev@illwieckz.net>
Sat, 18 May 2019 20:47:42 +0000 (22:47 +0200)
optional installation following Filesystem Hierarchy Standard

12 files changed:
CMakeLists.txt
Makefile
contrib/CMakeLists.txt
plugins/CMakeLists.txt
radiant/environment.cpp
radiant/environment.h
radiant/help.cpp
radiant/main.cpp
radiant/mainframe.cpp
radiant/mainframe.h
radiant/plugintoolbar.cpp
radiant/preferences.cpp

index aada8ec..7bc6391 100644 (file)
@@ -5,11 +5,29 @@ project(NetRadiant C CXX)
 option(BUILD_RADIANT "Build the GUI" ON)
 option(BUILD_CRUNCH "Build Crunch image support" OFF)
 option(USE_WERROR "Build with -Werror -pedantic-errors" OFF)
+option(STANDARD_INSTALL "Install following Filesystem Hierarchy Standard" OFF)
+
+#-----------------------------------------------------------------------
+# Paths
+#-----------------------------------------------------------------------
 
 if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
     set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/install" CACHE PATH "..." FORCE)
 endif ()
 
+set(RADIANT_BASENAME netradiant CACHE INTERNAL "...")
+add_definitions(-DRADIANT_BASENAME="${RADIANT_BASENAME}")
+
+set(RADIANT_LIB_SUBDIR . CACHE INTERNAL "...")
+set(RADIANT_BIN_SUBDIR . CACHE INTERNAL "...")
+set(RADIANT_DATA_SUBDIR . CACHE INTERNAL "...")
+
+if (STANDARD_INSTALL)
+       set(RADIANT_LIB_SUBDIR lib/${RADIANT_BASENAME})
+       set(RADIANT_BIN_SUBDIR bin)
+       set(RADIANT_DATA_SUBDIR share/${RADIANT_BASENAME})
+endif ()
+
 #-----------------------------------------------------------------------
 # Version
 #-----------------------------------------------------------------------
@@ -209,7 +227,7 @@ macro(radiant_tool name)
     add_executable(${name} ${ARGN})
     install(
             TARGETS ${name}
-            RUNTIME DESTINATION .
+            RUNTIME DESTINATION ${RADIANT_BIN_SUBDIR}/.
     )
     if (NOT (CMAKE_EXECUTABLE_SUFFIX STREQUAL ".${RADIANT_EXECUTABLE}"))
         add_custom_command(TARGET ${name} POST_BUILD
@@ -217,7 +235,7 @@ macro(radiant_tool name)
                 VERBATIM
                 )
         install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
-                ${name}${CMAKE_EXECUTABLE_SUFFIX} ${CMAKE_INSTALL_PREFIX}/${name}.${RADIANT_EXECUTABLE})
+                ${name}${CMAKE_EXECUTABLE_SUFFIX} ${CMAKE_INSTALL_PREFIX}/${RADIANT_BIN_SUBDIR}/${name}.${RADIANT_EXECUTABLE})
                 ")
     endif ()
 endmacro()
@@ -267,10 +285,10 @@ install(
         DIRECTORY
         setup/data/tools/
         docs
-        DESTINATION .
+        DESTINATION ${RADIANT_DATA_SUBDIR}/.
 )
 
-install(CODE "execute_process(COMMAND \"${PROJECT_SOURCE_DIR}/gamepack-manager\" --license ${GAMEPACKS_LICENSE_LIST} --name ${GAMEPACKS_NAME_LIST} --download-dir \"${PROJECT_BINARY_DIR}/download\" --install-dir \"${CMAKE_INSTALL_PREFIX}\" --install)"
+install(CODE "execute_process(COMMAND \"${PROJECT_SOURCE_DIR}/gamepack-manager\" --license ${GAMEPACKS_LICENSE_LIST} --name ${GAMEPACKS_NAME_LIST} --download-dir \"${PROJECT_BINARY_DIR}/download\" --install-dir \"${CMAKE_INSTALL_PREFIX}/${RADIANT_DATA_SUBDIR}\" --install)"
 )
 
 include(cmake/scripts/package.cmake)
index 009a3d0..51d9722 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,7 @@ CXXFLAGS           ?=
 CPPFLAGS           ?=
 LIBS               ?=
 RADIANT_ABOUTMSG   ?= Custom build
+RADIANT_BASENAME   ?= netradiant
 
 # warning: this directory may NOT contain any files other than the ones written by this Makefile!
 # NEVER SET THIS TO A SYSTEM WIDE "bin" DIRECTORY!
@@ -261,7 +262,7 @@ ifneq ($(GIT_VERSION),)
        Q3MAP_VERSION := $(Q3MAP_VERSION)-git-$(GIT_VERSION)
 endif
 
-CPPFLAGS += -DRADIANT_VERSION="\"$(RADIANT_VERSION)\"" -DRADIANT_MAJOR_VERSION="\"$(RADIANT_MAJOR_VERSION)\"" -DRADIANT_MINOR_VERSION="\"$(RADIANT_MINOR_VERSION)\"" -DRADIANT_PATCH_VERSION="\"$(RADIANT_PATCH_VERSION)\"" -DRADIANT_ABOUTMSG="\"$(RADIANT_ABOUTMSG)\"" -DQ3MAP_VERSION="\"$(Q3MAP_VERSION)\"" -DRADIANT_EXECUTABLE="\"$(RADIANT_EXECUTABLE)\""
+CPPFLAGS += -DRADIANT_VERSION="\"$(RADIANT_VERSION)\"" -DRADIANT_MAJOR_VERSION="\"$(RADIANT_MAJOR_VERSION)\"" -DRADIANT_MINOR_VERSION="\"$(RADIANT_MINOR_VERSION)\"" -DRADIANT_PATCH_VERSION="\"$(RADIANT_PATCH_VERSION)\"" -DRADIANT_ABOUTMSG="\"$(RADIANT_ABOUTMSG)\"" -DRADIANT_BASENAME="\"${RADIANT_BASENAME}\"" -DQ3MAP_VERSION="\"$(Q3MAP_VERSION)\"" -DRADIANT_EXECUTABLE="\"$(RADIANT_EXECUTABLE)\""
 CPPFLAGS += -DGTK_TARGET=2
 
 .PHONY: all
index 8233ea1..468b4f1 100644 (file)
@@ -8,7 +8,7 @@ macro(radiant_plugin name)
     copy_dlls(${name})
     install(
             TARGETS ${name}
-            LIBRARY DESTINATION plugins
+            LIBRARY DESTINATION ${RADIANT_LIB_SUBDIR}/plugins
     )
 endmacro()
 
index 80f45f1..808f311 100644 (file)
@@ -8,7 +8,7 @@ macro(radiant_plugin name)
     copy_dlls(${name})
     install(
             TARGETS ${name}
-            LIBRARY DESTINATION modules
+            LIBRARY DESTINATION ${RADIANT_LIB_SUBDIR}/modules
     )
 endmacro()
 
index 484258d..b38ef99 100644 (file)
@@ -167,6 +167,8 @@ namespace
 {
 CopiedString home_path;
 CopiedString app_path;
+       CopiedString lib_path;
+       CopiedString data_path;
 }
 
 const char* environment_get_home_path(){
@@ -177,10 +179,21 @@ const char* environment_get_app_path(){
        return app_path.c_str();
 }
 
+
+const char *environment_get_lib_path()
+{
+       return lib_path.c_str();
+}
+
+const char *environment_get_data_path()
+{
+       return data_path.c_str();
+}
+
 bool portable_app_setup(){
        StringOutputStream confdir( 256 );
        confdir << app_path.c_str() << "settings/";
-       if ( file_exists( confdir.c_str() ) ) {
+       if ( file_is_directory( confdir.c_str() ) ) {
                home_path = confdir.c_str();
                return true;
        }
@@ -251,9 +264,31 @@ void environment_init( int argc, char const* argv[] ){
                ASSERT_MESSAGE( !string_empty( app_path.c_str() ), "failed to deduce app path" );
        }
 
+       {
+               StringOutputStream buffer;
+               buffer << app_path.c_str() << "../lib/" << RADIANT_BASENAME << "/";
+               if ( file_is_directory( buffer.c_str() ) ) {
+                       lib_path = buffer.c_str();
+               }
+               else {
+                       lib_path = app_path.c_str();
+               }
+       }
+
+       {
+               StringOutputStream buffer;
+               buffer << app_path.c_str() << "../share/" << RADIANT_BASENAME << "/";
+               if ( file_is_directory( buffer.c_str() ) ) {
+                       data_path = buffer.c_str();
+               }
+               else {
+                       data_path = app_path.c_str();
+               }
+       }
+
        if ( !portable_app_setup() ) {
                StringOutputStream home( 256 );
-               home << DirectoryCleaned( g_get_user_config_dir() ) << "netradiant/";
+               home << DirectoryCleaned(g_get_user_config_dir()) << "/" << RADIANT_BASENAME << "/";
                Q_mkdir( home.c_str() );
                home_path = home.c_str();
        }
@@ -282,6 +317,9 @@ void environment_init( int argc, char const* argv[] ){
                StringOutputStream app( 256 );
                app << PathCleaned( filename );
                app_path = app.c_str();
+
+               lib_path = app_path;
+               data_path = app_path;
        }
 
        if ( !portable_app_setup() ) {
index b2828f8..d5d30e1 100644 (file)
@@ -26,6 +26,10 @@ void environment_init( int argc, char const* argv[] );
 const char* environment_get_home_path();
 const char* environment_get_app_path();
 
+const char *environment_get_lib_path();
+
+const char *environment_get_data_path();
+
 extern int g_argc;
 extern char const** g_argv;
 
index b11743d..0b6bf29 100644 (file)
@@ -115,8 +115,8 @@ void process_xlink( const char* filename, const char *menu_name, const char *bas
 
 void create_game_help_menu( ui::Menu menu ){
        StringOutputStream filename( 256 );
-       filename << AppPath_get() << "global.xlink";
-       process_xlink( filename.c_str(), "General", AppPath_get(), menu );
+       filename << DataPath_get() << "global.xlink";
+       process_xlink(filename.c_str(), "General", DataPath_get(), menu);
 
 #if 1
        filename.clear();
index a9cde39..0047cf2 100644 (file)
@@ -330,6 +330,8 @@ void paths_init(){
        Q_mkdir( g_strSettingsPath.c_str() );
 
        g_strAppPath = environment_get_app_path();
+       g_strLibPath = environment_get_lib_path();
+       g_strDataPath = environment_get_data_path();
 
        // radiant is installed in the parent dir of "tools/"
        // NOTE: this is not very easy for debugging
@@ -337,12 +339,12 @@ void paths_init(){
        // (for now I had to create symlinks)
        {
                StringOutputStream path( 256 );
-               path << g_strAppPath.c_str() << "bitmaps/";
+               path << g_strDataPath.c_str() << "bitmaps/";
                BitmapsPath_set( path.c_str() );
        }
 
        // we will set this right after the game selection is done
-       g_strGameToolsPath = g_strAppPath;
+       g_strGameToolsPath = g_strDataPath;
 }
 
 bool check_version_file( const char* filename, const char* version ){
index 1d3660f..b1f586b 100644 (file)
@@ -437,11 +437,23 @@ void setPakPath( int num, const char* path ){
 // App Path
 
 CopiedString g_strAppPath;                 ///< holds the full path of the executable
+CopiedString g_strLibPath;
+CopiedString g_strDataPath;
 
 const char* AppPath_get(){
        return g_strAppPath.c_str();
 }
 
+const char *LibPath_get()
+{
+    return g_strLibPath.c_str();
+}
+
+const char *DataPath_get()
+{
+    return g_strDataPath.c_str();
+}
+
 /// the path to the local rc-dir
 const char* LocalRcPath_get( void ){
        static CopiedString rc_path;
@@ -753,7 +765,7 @@ void Radiant_detachGameToolsPathObserver( ModuleObserver& observer ){
 void Radiant_Initialise(){
        GlobalModuleServer_Initialise();
 
-       Radiant_loadModulesFromRoot( AppPath_get() );
+       Radiant_loadModulesFromRoot( LibPath_get() );
 
        Preferences_Load();
 
index 85e60f4..358b9eb 100644 (file)
@@ -213,7 +213,12 @@ extern CopiedString g_strPakPath[g_pakPathCount];
 const char* PakPath_get( int num );
 
 extern CopiedString g_strAppPath;
+extern CopiedString g_strLibPath;
+extern CopiedString g_strDataPath;
+
 const char* AppPath_get();
+const char *LibPath_get();
+const char *DataPath_get();
 
 extern CopiedString g_strSettingsPath;
 const char* SettingsPath_get();
index aea1b32..e06491d 100644 (file)
@@ -42,13 +42,13 @@ ui::Image new_plugin_image( const char* filename ){
 
        {
                StringOutputStream fullpath( 256 );
-               fullpath << AppPath_get() << g_pluginsDir << "bitmaps/" << filename;
+               fullpath << DataPath_get() << g_pluginsDir << "bitmaps/" << filename;
                if ( auto image = image_new_from_file_with_mask(fullpath.c_str()) ) return image;
        }
 
        {
                StringOutputStream fullpath( 256 );
-               fullpath << AppPath_get() << g_modulesDir << "bitmaps/" << filename;
+               fullpath << DataPath_get() << g_modulesDir << "bitmaps/" << filename;
                if ( auto image = image_new_from_file_with_mask(fullpath.c_str()) ) return image;
        }
 
index 091a88f..3186c67 100644 (file)
@@ -121,7 +121,7 @@ CGameDescription::CGameDescription( xmlDocPtr pDoc, const CopiedString& gameFile
 
        {
                StringOutputStream path( 256 );
-               path << AppPath_get() << gameFile.c_str() << "/";
+               path << DataPath_get() << gameFile.c_str() << "/";
                mGameToolsPath = path.c_str();
        }
 
@@ -341,7 +341,7 @@ ui::Window CGameDialog::BuildDialog(){
 
 void CGameDialog::ScanForGames(){
        StringOutputStream strGamesPath( 256 );
-       strGamesPath << AppPath_get() << "games/";
+       strGamesPath << DataPath_get() << "games/";
        const char *path = strGamesPath.c_str();
 
        globalOutputStream() << "Scanning for game description files: " << path << '\n';