From 90d4acd1a1c9abeb31548d152c155491e2cf98fa Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Wed, 23 Mar 2022 13:20:14 +0100 Subject: [PATCH] refactor: combine portable and system builds Portable builds now have the same layout as system builds. If you want to build a portable bundle, you now need to additionally install the `portable` component. For example: $ cmake -Bbuild -DCMAKE_INSTALL_PREFIX=install ... $ cmake --build build $ cmake --install build $ cmake --install build --component portable --- CMakeLists.txt | 56 +++++++++++++++---------------------- launcher/Application.cpp | 53 ++++++++++++++++++----------------- launcher/Launcher.in | 2 +- program_info/CMakeLists.txt | 2 ++ program_info/portable.txt | 4 +++ 5 files changed, 58 insertions(+), 59 deletions(-) create mode 100644 program_info/portable.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 1350a3bab..cf06fe0df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,13 +165,12 @@ add_subdirectory(program_info) ####################################### Install layout ####################################### -# Install the build results according to platform -set(Launcher_PORTABLE 1 CACHE BOOL "The type of installation (Portable or System)") +# TODO: drop this? +# Target install directory, relative to CMAKE_INSTALL_PREFIx +set(BUNDLE_DEST_DIR ".") -if (Launcher_PORTABLE) - # launcher/Application.cpp will use this value - set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_PORTABLE") -endif() +# Install "portable.txt" if selected component is "portable" +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_Portable_File}" DESTINATION ${BUNDLE_DEST_DIR} COMPONENT portable EXCLUDE_FROM_ALL) if(UNIX AND APPLE) set(BINARY_DEST_DIR "${Launcher_Name}.app/Contents/MacOS") @@ -180,8 +179,6 @@ if(UNIX AND APPLE) set(RESOURCES_DEST_DIR "${Launcher_Name}.app/Contents/Resources") set(JARS_DEST_DIR "${Launcher_Name}.app/Contents/MacOS/jars") - set(BUNDLE_DEST_DIR ".") - # Apps to bundle set(APPS "\${CMAKE_INSTALL_PREFIX}/${Launcher_Name}.app") @@ -206,30 +203,12 @@ if(UNIX AND APPLE) elseif(UNIX) set(BINARY_DEST_DIR "bin") - if(Launcher_PORTABLE) - set(LIBRARY_DEST_DIR "bin") - set(BUNDLE_DEST_DIR ".") - set(JARS_DEST_DIR "bin/jars") - - # Install basic runner script - configure_file(launcher/Launcher.in "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" @ONLY) - install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION ${BUNDLE_DEST_DIR} RENAME ${Launcher_Name}) - else() - set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") - set(JARS_DEST_DIR "share/jars") - set(LAUNCHER_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file directory") - set(LAUNCHER_METAINFO_DEST_DIR "share/metainfo" CACHE STRING "Path to the metainfo directory") - set(LAUNCHER_ICON_DEST_DIR "share/icons/hicolor/scalable/apps" CACHE STRING "Path to the scalable icon directory") - set(LAUNCHER_MAN_DEST_DIR "share/man/man6" CACHE STRING "Path to the man page directory") - - # jars path is determined on runtime, relative to "Application root path", generally /usr for Launcher_PORTABLE=0 - set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_JARS_LOCATION=${JARS_DEST_DIR}") - - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${LAUNCHER_ICON_DEST_DIR}) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_ManPage} DESTINATION ${LAUNCHER_MAN_DEST_DIR} RENAME "${Launcher_APP_BINARY_NAME}.6") - endif() + set(LIBRARY_DEST_DIR "lib${LIB_SUFFIX}") + set(JARS_DEST_DIR "share/jars") + set(LAUNCHER_DESKTOP_DEST_DIR "share/applications" CACHE STRING "Path to the desktop file directory") + set(LAUNCHER_METAINFO_DEST_DIR "share/metainfo" CACHE STRING "Path to the metainfo directory") + set(LAUNCHER_ICON_DEST_DIR "share/icons/hicolor/scalable/apps" CACHE STRING "Path to the scalable icon directory") + set(LAUNCHER_MAN_DEST_DIR "share/man/man6" CACHE STRING "Path to the man page directory") # install as bundle with no dependencies included set(INSTALL_BUNDLE "nodeps") @@ -237,11 +216,22 @@ elseif(UNIX) # Set RPATH SET(Launcher_BINARY_RPATH "$ORIGIN/") + # jars path is determined on runtime, relative to "Application root path", generally /usr or the root of the portable bundle + set(Launcher_APP_BINARY_DEFS "-DLAUNCHER_JARS_LOCATION=${JARS_DEST_DIR}") + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_Desktop} DESTINATION ${LAUNCHER_DESKTOP_DEST_DIR}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${Launcher_MetaInfo} DESTINATION ${LAUNCHER_METAINFO_DEST_DIR}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_SVG} DESTINATION ${LAUNCHER_ICON_DEST_DIR}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${Launcher_ManPage} DESTINATION ${LAUNCHER_MAN_DEST_DIR} RENAME "${Launcher_APP_BINARY_NAME}.6") + + # Install basic runner script if component "portable" is selected + configure_file(launcher/Launcher.in "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" @ONLY) + install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/LauncherScript" DESTINATION ${BUNDLE_DEST_DIR} RENAME ${Launcher_Name} COMPONENT portable EXCLUDE_FROM_ALL) + elseif(WIN32) set(BINARY_DEST_DIR ".") set(LIBRARY_DEST_DIR ".") set(PLUGIN_DEST_DIR ".") - set(BUNDLE_DEST_DIR ".") set(RESOURCES_DEST_DIR ".") set(JARS_DEST_DIR "jars") diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 9cca534c3..a9f7a0f08 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -316,6 +316,26 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QString origcwdPath = QDir::currentPath(); QString binPath = applicationDirPath(); + + { + // Root path is used for updates and portable data +#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) + QDir foo(FS::PathCombine(binPath, "..")); // typically portable-root or /usr + m_rootPath = foo.absolutePath(); +#elif defined(Q_OS_WIN32) + m_rootPath = binPath; +#elif defined(Q_OS_MAC) + QDir foo(FS::PathCombine(binPath, "../..")); + m_rootPath = foo.absolutePath(); + // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues) + FS::updateTimestamp(m_rootPath); +#endif + +#ifdef LAUNCHER_JARS_LOCATION + m_jarsPath = TOSTRING(LAUNCHER_JARS_LOCATION); +#endif + } + QString adjustedBy; QString dataPath; // change folder @@ -324,15 +344,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) { // the dir param. it makes multimc data path point to whatever the user specified // on command line - adjustedBy += "Command line " + dirParam; + adjustedBy = "Command line"; dataPath = dirParam; } else { -#if !defined(LAUNCHER_PORTABLE) || defined(Q_OS_MAC) QDir foo(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), "..")); dataPath = foo.absolutePath(); - adjustedBy += dataPath; + adjustedBy = "Persistent data path"; #ifdef Q_OS_LINUX // TODO: this should be removed in a future version @@ -340,13 +359,14 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) QDir bar(FS::PathCombine(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), "polymc")); if (bar.exists()) { dataPath = bar.absolutePath(); - adjustedBy += "Legacy data path " + dataPath; + adjustedBy = "Legacy data path"; } #endif -#else - dataPath = applicationDirPath(); - adjustedBy += "Fallback to binary path " + dataPath; -#endif + + if (QFile::exists(FS::PathCombine(m_rootPath, "portable.txt"))) { + dataPath = m_rootPath; + adjustedBy = "Portable data path"; + } } if (!FS::ensureFolderPathExists(dataPath)) @@ -535,24 +555,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) qDebug() << "<> Log initialized."; } - // Set up paths { - // Root path is used for updates. -#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) - QDir foo(FS::PathCombine(binPath, "..")); - m_rootPath = foo.absolutePath(); -#elif defined(Q_OS_WIN32) - m_rootPath = binPath; -#elif defined(Q_OS_MAC) - QDir foo(FS::PathCombine(binPath, "../..")); - m_rootPath = foo.absolutePath(); - // on macOS, touch the root to force Finder to reload the .app metadata (and fix any icon change issues) - FS::updateTimestamp(m_rootPath); -#endif - -#ifdef LAUNCHER_JARS_LOCATION - m_jarsPath = TOSTRING(LAUNCHER_JARS_LOCATION); -#endif qDebug() << BuildConfig.LAUNCHER_DISPLAYNAME << ", (c) 2013-2021 " << BuildConfig.LAUNCHER_COPYRIGHT; qDebug() << "Version : " << BuildConfig.printableVersionString(); diff --git a/launcher/Launcher.in b/launcher/Launcher.in index 5e5e2c2bc..528e360eb 100755 --- a/launcher/Launcher.in +++ b/launcher/Launcher.in @@ -21,7 +21,7 @@ echo "Launcher Dir: ${LAUNCHER_DIR}" # Set up env - filter out input LD_ variables but pass them in under different names export GAME_LIBRARY_PATH=${GAME_LIBRARY_PATH-${LD_LIBRARY_PATH}} export GAME_PRELOAD=${GAME_PRELOAD-${LD_PRELOAD}} -export LD_LIBRARY_PATH="${LAUNCHER_DIR}/bin":$LAUNCHER_LIBRARY_PATH +export LD_LIBRARY_PATH="${LAUNCHER_DIR}/lib@LIB_SUFFIX@":$LAUNCHER_LIBRARY_PATH export LD_PRELOAD=$LAUNCHER_PRELOAD export QT_PLUGIN_PATH="${LAUNCHER_DIR}/plugins" export QT_FONTPATH="${LAUNCHER_DIR}/fonts" diff --git a/program_info/CMakeLists.txt b/program_info/CMakeLists.txt index 9c243826a..60549d8d3 100644 --- a/program_info/CMakeLists.txt +++ b/program_info/CMakeLists.txt @@ -17,5 +17,7 @@ set(Launcher_Branding_ICNS "program_info/polymc.icns" PARENT_SCOPE) set(Launcher_Branding_WindowsRC "program_info/polymc.rc" PARENT_SCOPE) set(Launcher_Branding_LogoQRC "program_info/polymc.qrc" PARENT_SCOPE) +set(Launcher_Portable_File "program_info/portable.txt" PARENT_SCOPE) + configure_file(org.polymc.PolyMC.desktop.in org.polymc.PolyMC.desktop) configure_file(org.polymc.PolyMC.metainfo.xml.in org.polymc.PolyMC.metainfo.xml) diff --git a/program_info/portable.txt b/program_info/portable.txt new file mode 100644 index 000000000..b7e256a21 --- /dev/null +++ b/program_info/portable.txt @@ -0,0 +1,4 @@ +This file enables the portable mode for the launcher. + +If this file is present in the root directory of the launcher, it will store all data here. Otherwise it will store your data in your appdata directory. +You can safely delete this file, if you don't want the launcher to store your data here.