From cda18b9cb32ccafdfe09a5dd2b564fcea2dd54aa Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 4 Nov 2018 02:01:48 +0100 Subject: [PATCH] cmake: FHS installation optional installation following Filesystem Hierarchy Standard --- CMakeLists.txt | 26 ++++++++++++++++++++---- Makefile | 3 ++- contrib/CMakeLists.txt | 2 +- plugins/CMakeLists.txt | 2 +- radiant/environment.cpp | 42 +++++++++++++++++++++++++++++++++++++-- radiant/environment.h | 4 ++++ radiant/help.cpp | 4 ++-- radiant/main.cpp | 6 ++++-- radiant/mainframe.cpp | 14 ++++++++++++- radiant/mainframe.h | 5 +++++ radiant/plugintoolbar.cpp | 4 ++-- radiant/preferences.cpp | 4 ++-- 12 files changed, 98 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aada8ecd..7bc63919 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/Makefile b/Makefile index 009a3d06..51d97220 100644 --- 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 diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 8233ea1e..468b4f12 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -8,7 +8,7 @@ macro(radiant_plugin name) copy_dlls(${name}) install( TARGETS ${name} - LIBRARY DESTINATION plugins + LIBRARY DESTINATION ${RADIANT_LIB_SUBDIR}/plugins ) endmacro() diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 80f45f1f..808f3110 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -8,7 +8,7 @@ macro(radiant_plugin name) copy_dlls(${name}) install( TARGETS ${name} - LIBRARY DESTINATION modules + LIBRARY DESTINATION ${RADIANT_LIB_SUBDIR}/modules ) endmacro() diff --git a/radiant/environment.cpp b/radiant/environment.cpp index 484258d7..b38ef992 100644 --- a/radiant/environment.cpp +++ b/radiant/environment.cpp @@ -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() ) { diff --git a/radiant/environment.h b/radiant/environment.h index b2828f86..d5d30e1c 100644 --- a/radiant/environment.h +++ b/radiant/environment.h @@ -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; diff --git a/radiant/help.cpp b/radiant/help.cpp index b11743d6..0b6bf297 100644 --- a/radiant/help.cpp +++ b/radiant/help.cpp @@ -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(); diff --git a/radiant/main.cpp b/radiant/main.cpp index a9cde39c..0047cf25 100644 --- a/radiant/main.cpp +++ b/radiant/main.cpp @@ -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 ){ diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 1d3660f5..b1f586bc 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -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(); diff --git a/radiant/mainframe.h b/radiant/mainframe.h index 85e60f47..358b9eb7 100644 --- a/radiant/mainframe.h +++ b/radiant/mainframe.h @@ -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(); diff --git a/radiant/plugintoolbar.cpp b/radiant/plugintoolbar.cpp index aea1b321..e06491d8 100644 --- a/radiant/plugintoolbar.cpp +++ b/radiant/plugintoolbar.cpp @@ -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; } diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 091a88f3..3186c67f 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -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'; -- 2.39.2