From 89f511185136a8065d97cdc7fcda9b52f6ddd0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert-Andr=C3=A9=20Mauchin?= Date: Sat, 14 Oct 2023 22:52:15 +0200 Subject: [PATCH] Split data, libraries and binary and try to respect the FHS on Linux --- src/CMakeLists.txt | 30 ++++++++++++++++---- src/RageFileManager.cpp | 9 ++++-- src/RageFileManager.h | 2 ++ src/arch/ArchHooks/ArchHooks.h | 4 +-- src/arch/ArchHooks/ArchHooks_MacOSX.mm | 10 +++---- src/arch/ArchHooks/ArchHooks_Unix.cpp | 12 ++++---- src/arch/ArchHooks/ArchHooks_Unix.h | 2 +- src/arch/LoadingWindow/LoadingWindow_Gtk.cpp | 2 +- src/config.in.h | 4 +++ 9 files changed, 52 insertions(+), 23 deletions(-) create mode 100644 src/config.in.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0feb8ed722..1708c84ffd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,9 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) # Main project is below. +if(UNIX OR LINUX) +include(GNUInstallDirs) +endif() include(CMakeData-arch.cmake) include(CMakeData-rage.cmake) @@ -645,6 +648,7 @@ else() # Unix / Linux TODO: Remember to find and locate the zip archive files. endif() target_link_libraries("${SM_EXE_NAME}" ${SMDATA_LINK_LIB}) +target_include_directories("${SM_EXE_NAME}" PRIVATE ${CMAKE_BINARY_DIR}) list(APPEND SM_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} "${SM_SRC_DIR}/generated") @@ -727,12 +731,26 @@ endif() target_include_directories("${SM_EXE_NAME}" PUBLIC ${SM_INCLUDE_DIRS}) -if(WIN32) - set(SM_INSTALL_DESTINATION ".") -else() - set(SM_INSTALL_DESTINATION "stepmania-5.1") +if (NOT DEFINED SM_INSTALL_DESTINATION) + if(WIN32) + set(SM_INSTALL_DESTINATION "." CACHE PATH "Installation directory") + elseif(APPLE) + set(SM_INSTALL_DESTINATION "stepmania-5.0" CACHE PATH "Installation directory") + else() + set(SM_INSTALL_DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/stepmania" CACHE PATH "Installation directory") + endif() endif() +if (NOT DEFINED SM_LIBDIR_DESTINATION) + if(UNIX OR LINUX) + set(SM_LIBDIR_DESTINATION "${CMAKE_INSTALL_LIBDIR}/stepmania" CACHE PATH "Libraries directory") + else() + set(SM_LIBDIR_DESTINATION "${SM_INSTALL_DESTINATION}" CACHE PATH "Libraries directory") + endif() +endif() + +configure_file(config.in.h "${CMAKE_BINARY_DIR}/config.h" @ONLY) + if(NOT APPLE) if(WIN32) set(SM_FULL_INSTALLATION_PATH_LIST "${SM_INSTALL_DESTINATION}" "Program") @@ -760,11 +778,11 @@ if(NOT APPLE) # foreach(SM_WINDOW_DLL "${SM_WINDOWS_PROGRAM_DLLS}") install(FILES # "${SM_WINDOW_DLL}" DESTINATION "${SM_INSTALL_DESTINATION}") endforeach() else() - install(TARGETS "${SM_EXE_NAME}" DESTINATION "${SM_INSTALL_DESTINATION}") + install(TARGETS "${SM_EXE_NAME}" DESTINATION "${CMAKE_INSTALL_BINDIR}") endif() if(UNIX OR LINUX) install(FILES "${SM_ROOT_DIR}/GtkModule.so" - LIBRARY DESTINATION "${SM_INSTALL_DESTINATION}" OPTIONAL) + LIBRARY DESTINATION "${SM_LIBDIR_DESTINATION}" OPTIONAL) endif() install(DIRECTORY "${SM_ROOT_DIR}/Announcers" DESTINATION "${SM_INSTALL_DESTINATION}") diff --git a/src/RageFileManager.cpp b/src/RageFileManager.cpp index 950012f3f7..a3cc46f2e5 100644 --- a/src/RageFileManager.cpp +++ b/src/RageFileManager.cpp @@ -1,3 +1,4 @@ +#include "config.h" #include "global.h" #include "RageFileManager.h" #include "RageFileDriver.h" @@ -24,6 +25,8 @@ static RageEvent *g_Mutex; RString RageFileManagerUtil::sInitialWorkingDirectory; RString RageFileManagerUtil::sDirOfExecutable; +RString RageFileManagerUtil::sDirOfData; +RString RageFileManagerUtil::sDirOfLibraries; struct LoadedDriver { @@ -278,6 +281,8 @@ static void ChangeToDirOfExecutable( const RString &argv0 ) { RageFileManagerUtil::sInitialWorkingDirectory = GetCwd(); RageFileManagerUtil::sDirOfExecutable = GetDirOfExecutable( argv0 ); + RageFileManagerUtil::sDirOfData = SM_INSTALL_DESTINATION; + RageFileManagerUtil::sDirOfLibraries = SM_LIBDIR_DESTINATION; /* Set the CWD. Any effects of this is platform-specific; most files are read and * written through RageFile. See also RageFileManager::RageFileManager. */ @@ -327,12 +332,12 @@ RageFileManager::RageFileManager( const RString &argv0 ) void RageFileManager::MountInitialFilesystems() { - HOOKS->MountInitialFilesystems( RageFileManagerUtil::sDirOfExecutable ); + HOOKS->MountInitialFilesystems( RageFileManagerUtil::sDirOfData ); } void RageFileManager::MountUserFilesystems() { - HOOKS->MountUserFilesystems( RageFileManagerUtil::sDirOfExecutable ); + HOOKS->MountUserFilesystems( RageFileManagerUtil::sDirOfData ); } RageFileManager::~RageFileManager() diff --git a/src/RageFileManager.h b/src/RageFileManager.h index c6ef53520c..f6aafa1757 100644 --- a/src/RageFileManager.h +++ b/src/RageFileManager.h @@ -5,6 +5,8 @@ namespace RageFileManagerUtil { extern RString sInitialWorkingDirectory; extern RString sDirOfExecutable; + extern RString sDirOfData; + extern RString sDirOfLibraries; } class RageFileDriver; diff --git a/src/arch/ArchHooks/ArchHooks.h b/src/arch/ArchHooks/ArchHooks.h index 123a320343..42040fa199 100644 --- a/src/arch/ArchHooks/ArchHooks.h +++ b/src/arch/ArchHooks/ArchHooks.h @@ -91,12 +91,12 @@ public: /* * Add file search paths, higher priority first. */ - static void MountInitialFilesystems( const RString &sDirOfExecutable ); + static void MountInitialFilesystems( const RString &sDirOfData ); /* * Add file search paths for user-writable directories. */ - static void MountUserFilesystems( const RString &sDirOfExecutable ); + static void MountUserFilesystems( const RString &sDirOfData ); /* * Platform-specific code calls this to indicate focus changes. diff --git a/src/arch/ArchHooks/ArchHooks_MacOSX.mm b/src/arch/ArchHooks/ArchHooks_MacOSX.mm index cfb37d2eba..f06b60dfd7 100644 --- a/src/arch/ArchHooks/ArchHooks_MacOSX.mm +++ b/src/arch/ArchHooks/ArchHooks_MacOSX.mm @@ -316,26 +316,26 @@ static void PathForFolderType( char dir[PATH_MAX], OSType folderType ) FAIL_M( "FSRefMakePath() failed." ); } -void ArchHooks::MountInitialFilesystems( const RString &sDirOfExecutable ) +void ArchHooks::MountInitialFilesystems( const RString &sDirOfData ) { char dir[PATH_MAX]; CFURLRef dataUrl = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("StepMania"), CFSTR("smzip"), nil); - FILEMAN->Mount( "dir", sDirOfExecutable, "/" ); + FILEMAN->Mount( "dir", sDirOfData, "/" ); if( dataUrl ) { CFStringRef dataPath = CFURLCopyFileSystemPath( dataUrl, kCFURLPOSIXPathStyle ); CFStringGetCString( dataPath, dir, PATH_MAX, kCFStringEncodingUTF8 ); - if( strncmp(sDirOfExecutable, dir, sDirOfExecutable.length()) == 0 ) - FILEMAN->Mount( "zip", dir + sDirOfExecutable.length(), "/" ); + if( strncmp(sDirOfData, dir, sDirOfData.length()) == 0 ) + FILEMAN->Mount( "zip", dir + sDirOfData.length(), "/" ); CFRelease( dataPath ); CFRelease( dataUrl ); } } -void ArchHooks::MountUserFilesystems( const RString &sDirOfExecutable ) +void ArchHooks::MountUserFilesystems( const RString &sDirOfData ) { char dir[PATH_MAX]; diff --git a/src/arch/ArchHooks/ArchHooks_Unix.cpp b/src/arch/ArchHooks/ArchHooks_Unix.cpp index 3463f29997..fc73158361 100644 --- a/src/arch/ArchHooks/ArchHooks_Unix.cpp +++ b/src/arch/ArchHooks/ArchHooks_Unix.cpp @@ -384,14 +384,14 @@ RString ArchHooks_Unix::GetClipboard() #include static LocalizedString COULDNT_FIND_SONGS( "ArchHooks_Unix", "Couldn't find 'Songs'" ); -void ArchHooks::MountInitialFilesystems( const RString &sDirOfExecutable ) +void ArchHooks::MountInitialFilesystems( const RString &sDirOfData ) { RString Root; struct stat st; - if( !stat(sDirOfExecutable + "/Packages", &st) && st.st_mode&S_IFDIR ) - Root = sDirOfExecutable; - else if( !stat(sDirOfExecutable + "/Songs", &st) && st.st_mode&S_IFDIR ) - Root = sDirOfExecutable; + if( !stat(sDirOfData + "/Packages", &st) && st.st_mode&S_IFDIR ) + Root = sDirOfData; + else if( !stat(sDirOfData + "/Songs", &st) && st.st_mode&S_IFDIR ) + Root = sDirOfData; else if( !stat(RageFileManagerUtil::sInitialWorkingDirectory + "/Songs", &st) && st.st_mode&S_IFDIR ) Root = RageFileManagerUtil::sInitialWorkingDirectory; else @@ -400,7 +400,7 @@ void ArchHooks::MountInitialFilesystems( const RString &sDirOfExecutable ) FILEMAN->Mount( "dir", Root, "/" ); } -void ArchHooks::MountUserFilesystems( const RString &sDirOfExecutable ) +void ArchHooks::MountUserFilesystems( const RString &sDirOfData ) { /* Path to write general mutable user data when not Portable * Lowercase the PRODUCT_ID; dotfiles and directories are almost always lowercase. diff --git a/src/arch/ArchHooks/ArchHooks_Unix.h b/src/arch/ArchHooks/ArchHooks_Unix.h index fc1962f874..55603aff02 100644 --- a/src/arch/ArchHooks/ArchHooks_Unix.h +++ b/src/arch/ArchHooks/ArchHooks_Unix.h @@ -12,7 +12,7 @@ public: void SetTime( tm newtime ); int64_t GetMicrosecondsSinceStart(); - void MountInitialFilesystems( const RString &sDirOfExecutable ); + void MountInitialFilesystems( const RString &sDirOfData ); float GetDisplayAspectRatio() { return 4.0f/3; } bool GoToURL( RString sUrl ); diff --git a/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp b/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp index 4fb976fc98..118e6489b7 100644 --- a/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp +++ b/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp @@ -29,7 +29,7 @@ RString LoadingWindow_Gtk::Init() { ASSERT( Handle == nullptr ); - Handle = dlopen( RageFileManagerUtil::sDirOfExecutable + "/" + "GtkModule.so", RTLD_NOW ); + Handle = dlopen( RageFileManagerUtil::sDirOfLibraries + "/" + "GtkModule.so", RTLD_NOW ); if( Handle == nullptr ) return ssprintf( "dlopen(): %s", dlerror() ); diff --git a/src/config.in.h b/src/config.in.h new file mode 100644 index 0000000000..7a3992f53f --- /dev/null +++ b/src/config.in.h @@ -0,0 +1,4 @@ +#pragma once + +#define SM_INSTALL_DESTINATION "@CMAKE_INSTALL_PREFIX@/@SM_INSTALL_DESTINATION@" +#define SM_LIBDIR_DESTINATION "@CMAKE_INSTALL_PREFIX@/@SM_LIBDIR_DESTINATION@" -- 2.47.1