From 557f2c5c3ac3c17e365e80372524bff5e4b50d4c Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Mon, 24 Jan 2022 18:40:48 -0500 Subject: [PATCH] Move path to shared sst-plugininfra - Move the old PATHS stuff to sst-plugininfra - Rework the SurgeStorage resoultion. Closes #5097 - Temporarily modify the abuot screen retaining and expanding the 1.0 bug in #5825 --- .gitmodules | 3 + libs/sst/sst-cpputils | 1 + libs/sst/sst-plugininfra | 2 +- src/common/CMakeLists.txt | 7 +- src/common/SurgeStorage.cpp | 211 ++++------------------ src/platform/CMakeLists.txt | 14 +- src/platform/include/platform/Paths.h | 36 ---- src/platform/src/Paths.cpp | 31 ---- src/platform/unix/Paths.cpp | 43 ----- src/platform/windows/Paths.cpp | 65 ------- src/surge-xt/gui/overlays/AboutScreen.cpp | 6 +- 11 files changed, 57 insertions(+), 362 deletions(-) create mode 160000 libs/sst/sst-cpputils delete mode 100644 src/platform/include/platform/Paths.h delete mode 100644 src/platform/src/Paths.cpp delete mode 100644 src/platform/unix/Paths.cpp delete mode 100644 src/platform/windows/Paths.cpp diff --git a/.gitmodules b/.gitmodules index 7dd82054f8a..474b7ad5485 100644 --- a/.gitmodules +++ b/.gitmodules @@ -32,3 +32,6 @@ [submodule "libs/sst/sst-plugininfra"] path = libs/sst/sst-plugininfra url = https://github.com/surge-synthesizer/sst-plugininfra +[submodule "libs/sst/sst-cpputils"] + path = libs/sst/sst-cpputils + url = https://github.com/surge-synthesizer/sst-cpputils diff --git a/libs/sst/sst-cpputils b/libs/sst/sst-cpputils new file mode 160000 index 00000000000..916c8cdf516 --- /dev/null +++ b/libs/sst/sst-cpputils @@ -0,0 +1 @@ +Subproject commit 916c8cdf516ec13a11145b8efa6b7ee98146bdca diff --git a/libs/sst/sst-plugininfra b/libs/sst/sst-plugininfra index 440958f9663..c6976768deb 160000 --- a/libs/sst/sst-plugininfra +++ b/libs/sst/sst-plugininfra @@ -1 +1 @@ -Subproject commit 440958f9663fe6b014b91e02ec0cb6d5d9a027e0 +Subproject commit c6976768debe045505fc07d73afb502b51717120 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5d5ec990409..8bf693d9a00 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -14,6 +14,7 @@ surge_add_lib_subdirectory(tuning-library) surge_add_lib_subdirectory(sqlite-3.23.3) surge_add_lib_subdirectory(LuaJitLib) +surge_add_lib_subdirectory(sst/sst-cpputils) surge_add_lib_subdirectory(sst/sst-plugininfra) set(PEGTL_BUILD_TESTS OFF CACHE BOOL "") @@ -319,11 +320,15 @@ target_link_libraries(${PROJECT_NAME} samplerate surge::airwindows surge::eurorack + + sst-cpputils + sst-plugininfra sst-plugininfra::filesystem + sst-plugininfra::tinyxml + surge::oddsound-mts surge::sqlite surge::strnatcmp - sst-plugininfra::tinyxml surge-common-binary tuning-library PRIVATE diff --git a/src/common/SurgeStorage.cpp b/src/common/SurgeStorage.cpp index 24632952f08..c328392af3a 100644 --- a/src/common/SurgeStorage.cpp +++ b/src/common/SurgeStorage.cpp @@ -24,22 +24,8 @@ #include "UserDefaults.h" #include "SurgeSharedBinary.h" #include "DebugHelpers.h" -#include "platform/Paths.h" -#if MAC -#include -#include -//#include -//#include -#include -#include -#elif LINUX -#include -#else -#include -#include -#include -#endif +#include "sst/plugininfra/paths.h" #include #include @@ -202,18 +188,7 @@ SurgeStorage::SurgeStorage(std::string suppliedDataPath) : otherscene_clients(0) memset(&audio_in[0][0], 0, 2 * BLOCK_SIZE_OS * sizeof(float)); - bool hasSuppliedDataPath = false; - if (suppliedDataPath.size() != 0) - { - hasSuppliedDataPath = true; - } - -#if MAC || LINUX - const auto homePath{Surge::Paths::homePath()}; -#endif - -#if MAC - char path[1024]; + bool hasSuppliedDataPath = !suppliedDataPath.empty(); std::string buildOverrideDataPath; if (getOverrideDataHome(buildOverrideDataPath)) { @@ -222,166 +197,73 @@ SurgeStorage::SurgeStorage(std::string suppliedDataPath) : otherscene_clients(0) suppliedDataPath = buildOverrideDataPath; } + std::string sxt = "Surge XT"; + std::string sxtlower = "surge-xt"; + +#if MAC if (!hasSuppliedDataPath) { - FSRef foundRef; - OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &foundRef); - FSRefMakePath(&foundRef, (UInt8 *)path, 1024); - std::string localpath = path; - localpath += "/Surge XT/"; - - err = FSFindFolder(kLocalDomain, kApplicationSupportFolderType, false, &foundRef); - FSRefMakePath(&foundRef, (UInt8 *)path, 1024); - std::string rootpath = path; - rootpath += "/Surge XT/"; + auto shareddp = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxt); + auto userdp = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxt, true); - datapath = rootpath; - if (fs::is_directory(string_to_path(localpath))) - datapath = localpath; + if (fs::is_directory(userdp)) + datapath = userdp; + else + datapath = shareddp; } else { - datapath = suppliedDataPath; + datapath = fs::path{suppliedDataPath}; } - userDataPath = homePath / "Documents/Surge XT"; + userDataPath = sst::plugininfra::paths::bestDocumentsFolderPathFor("Surge XT"); #elif LINUX if (!hasSuppliedDataPath) { - if (const char *xdgDataPath = getenv("XDG_DATA_HOME")) - { - datapath = fs::path{xdgDataPath} / "surge-xt"; - } - else if (auto localDataPath{homePath / ".local/share/surge-xt"}; - fs::is_directory(localDataPath)) - { - datapath = std::move(localDataPath); - } - else - { - datapath = homePath / ".local/share/Surge XT"; - } - - /* - ** If local directory doesn't exists - we probably came here through an installer - - ** check for /usr/share/surge and use /usr/share/Surge as our last guess - */ - if (!fs::is_directory(datapath)) - { - if (fs::is_directory(string_to_path(std::string(Surge::Build::CMAKE_INSTALL_PREFIX)) / - "share" / "surge-xt")) - { - datapath = - string_to_path(Surge::Build::CMAKE_INSTALL_PREFIX) / "share" / "surge-xt"; - } - else if (fs::is_directory(string_to_path(Surge::Build::CMAKE_INSTALL_PREFIX) / "share" / - "Surge XT")) - { - datapath = - string_to_path(Surge::Build::CMAKE_INSTALL_PREFIX) / "share" / "Surge XT"; - } - else - { - std::string systemDataPath = "/usr/share/surge-xt/"; - if (fs::is_directory(string_to_path(systemDataPath))) - datapath = string_to_path(systemDataPath); - else - datapath = string_to_path("/usr/share/Surge XT/"); - } - } + auto userlower = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxtlower, true); + auto userreg = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxt, true); + auto globallower = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxtlower, false); + auto globalreg = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxt, true); - std::string buildOverrideDataPath; - if (getOverrideDataHome(buildOverrideDataPath)) + bool founddir{false}; + for (const auto &p : {userreg, userlower, globalreg, globallower}) { - datapathOverriden = true; - datapath = buildOverrideDataPath; - static bool warnOver = false; - if (!warnOver) + if (fs::is_directory(p) && !founddir) { - std::cout << "WARNING: Surge overriding data path to " << datapath << std::endl; - std::cout << " Only use this in build pipelines please!" << std::endl; - warnOver = true; + founddir = true; + datapath = p; } } + if (!founddir) + datapath = globallower; } else { datapath = suppliedDataPath; } - /* - ** See the discussion in github issue #930. Basically - ** if ~/Documents/Surge XT exists use that - ** else if ~/.Surge XT exists use that - ** else if ~/.Documents exists, use ~/Documents/Surge XT - ** else use ~/.Surge XT - ** Compensating for whether your distro makes you a ~/Documents or not - */ - - if (auto xdgdd = getenv("XDG_DOCUMENTS_DIR")) - { - auto xdgpath = fs::path{xdgdd} / "Surge XT"; - userDataPath = std::move(xdgpath); - } - else if (auto documentsSurge = homePath / "Documents/Surge XT"; - fs::is_directory(documentsSurge)) - { - userDataPath = std::move(documentsSurge); - } - else if (auto dotSurge = homePath / ".Surge XT"; fs::is_directory(dotSurge)) - { - userDataPath = std::move(dotSurge); - } - else if (auto documents = homePath / "Documents"; fs::is_directory(documents)) - { - userDataPath = std::move(documentsSurge); - } - else - { - userDataPath = dotSurge; - } - // std::cout << "Data path is " << datapath << std::endl; - // std::cout << "User data path is " << userDataPath << std::endl; + userDataPath = sst::plugininfra::paths::bestDocumentsFolderPathFor(sxt); #elif WINDOWS - const auto installPath{Surge::Paths::installPath()}; - - // First check the portable mode sitting beside me - if (auto path{installPath / L"SurgeXTData"}; fs::is_directory(path)) - { - datapath = std::move(path); - } + const auto installPath = sst::plugininfra::paths::sharedLibraryBinaryPath().parent_path(); - if (datapath.empty()) + if (!hasSuppliedDataPath) { - PWSTR commonAppData; - if (!SHGetKnownFolderPath(FOLDERID_ProgramData, 0, nullptr, &commonAppData)) + // First check the portable mode sitting beside me + if (auto path{installPath / L"SurgeXTData"}; fs::is_directory(path)) { - fs::path path(commonAppData); - path /= L"Surge XT"; - if (fs::is_directory(path)) - { - datapath = path_to_string(path); - } + datapath = std::move(path); } - } - if (datapath.empty()) - { - PWSTR localAppData; - if (!SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &localAppData)) + if (datapath.empty()) { - fs::path path(localAppData); - path /= L"Surge XT"; - datapath = path_to_string(path); + datapath = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxt); } - } - std::string orPath; - if (getOverrideDataHome(orPath)) - { - datapathOverriden = true; - datapath = orPath; + if (datapath.empty()) + { + datapath = sst::plugininfra::paths::bestLibrarySharedFolderPathFor(sxt, true); + } } // Portable - first check for installPath\\SurgeXTUserData @@ -389,11 +271,9 @@ SurgeStorage::SurgeStorage(std::string suppliedDataPath) : otherscene_clients(0) { userDataPath = std::move(path); } - else if (PWSTR documentsFolder; - !SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &documentsFolder)) + else { - userDataPath = fs::path{documentsFolder} / L"Surge XT"; - // FIXME: Don't leak documentsFolder! + userDataPath = sst::plugininfra::paths::bestDocumentsFolderPathFor(sxt); } #endif @@ -403,7 +283,7 @@ SurgeStorage::SurgeStorage(std::string suppliedDataPath) : otherscene_clients(0) Surge::Storage::getUserDefaultValue(this, Surge::Storage::UserDataPath, "UNSPEC"); if (userSpecifiedDataPath != "UNSPEC") { - userDataPath = userSpecifiedDataPath; + userDataPath = fs::path{userSpecifiedDataPath}; } // append separator if not present @@ -416,17 +296,6 @@ SurgeStorage::SurgeStorage(std::string suppliedDataPath) : otherscene_clients(0) userSkinsPath = userDataPath / "Skins"; createUserDirectory(); - /* - const auto snapshotmenupath{string_to_path(datapath + "configuration.xml")}; - - if (!snapshotloader.LoadFile(snapshotmenupath)) // load snapshots (& config-stuff) - { - reportError("Cannot find 'configuration.xml' in path '" + - datapath + "'. Please reinstall surge.", - "Surge is not properly installed."); - } - */ - // TIXML requires a newline at end. auto cxmlData = std::string(SurgeSharedBinary::configuration_xml, SurgeSharedBinary::configuration_xmlSize) + diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 1231119d9af..321e474a915 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -1,20 +1,12 @@ # vi:set sw=2 et: project(surge-platform) -add_library(${PROJECT_NAME} - include/platform/Paths.h - src/Paths.cpp - ) if(APPLE) - target_sources(${PROJECT_NAME} PRIVATE + add_library(${PROJECT_NAME} macos/cpp17-aligned-new.cpp - unix/Paths.cpp ) elseif(WIN32) - target_sources(${PROJECT_NAME} PRIVATE windows/Paths.cpp) + add_library(${PROJECT_NAME} INTERFACE) elseif(UNIX) - target_sources(${PROJECT_NAME} PRIVATE unix/Paths.cpp) - target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS}) + add_library(${PROJECT_NAME} INTERFACE) endif() -target_link_libraries(${PROJECT_NAME} PUBLIC sst-plugininfra::filesystem) -target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/src/platform/include/platform/Paths.h b/src/platform/include/platform/Paths.h deleted file mode 100644 index 4f2c725415d..00000000000 --- a/src/platform/include/platform/Paths.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -** Surge Synthesizer is Free and Open Source Software -** -** Surge is made available under the Gnu General Public License, v3.0 -** https://www.gnu.org/licenses/gpl-3.0.en.html -** -** Copyright 2004-2021 by various individuals as described by the Git transaction log -** -** All source at: https://github.com/surge-synthesizer/surge.git -** -** Surge was a commercial product from 2004-2018, with Copyright and ownership -** in that period held by Claes Johanson at Vember Audio. Claes made Surge -** open source in September 2018. -*/ - -#pragma once - -#include "filesystem/import.h" - -namespace Surge::Paths -{ - -/// @return The path of the running Surge application / plugin itself. Equivalent to binaryPath(), -/// except on macOS, where it returns the bundle directory (.app, .component, ...) -fs::path appPath(); - -/// @return The path of the running Surge binary file itself (.exe, .dll, .so, ...) -fs::path binaryPath(); - -/// @return The current user's home directory (e.g. /home/user, /Users/user, C:\Users\user) -fs::path homePath(); - -/// @return The directory where the running Surge application / plugin is installed -inline fs::path installPath() { return appPath().parent_path(); } - -} // namespace Surge::Paths diff --git a/src/platform/src/Paths.cpp b/src/platform/src/Paths.cpp deleted file mode 100644 index 3b2ea01ed7b..00000000000 --- a/src/platform/src/Paths.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -** Surge Synthesizer is Free and Open Source Software -** -** Surge is made available under the Gnu General Public License, v3.0 -** https://www.gnu.org/licenses/gpl-3.0.en.html -** -** Copyright 2004-2021 by various individuals as described by the Git transaction log -** -** All source at: https://github.com/surge-synthesizer/surge.git -** -** Surge was a commercial product from 2004-2018, with Copyright and ownership -** in that period held by Claes Johanson at Vember Audio. Claes made Surge -** open source in September 2018. -*/ - -#include "platform/Paths.h" - -namespace Surge::Paths -{ - -fs::path appPath() -{ -#ifdef __APPLE__ - // FIXME: This is what the old code did. We can probably do better... - return binaryPath().parent_path().parent_path().parent_path(); -#else - return binaryPath(); -#endif -} - -} // namespace Surge::Paths diff --git a/src/platform/unix/Paths.cpp b/src/platform/unix/Paths.cpp deleted file mode 100644 index b9f601a8868..00000000000 --- a/src/platform/unix/Paths.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -** Surge Synthesizer is Free and Open Source Software -** -** Surge is made available under the Gnu General Public License, v3.0 -** https://www.gnu.org/licenses/gpl-3.0.en.html -** -** Copyright 2004-2021 by various individuals as described by the Git transaction log -** -** All source at: https://github.com/surge-synthesizer/surge.git -** -** Surge was a commercial product from 2004-2018, with Copyright and ownership -** in that period held by Claes Johanson at Vember Audio. Claes made Surge -** open source in September 2018. -*/ - -#include "platform/Paths.h" -#include -#include -#include - -namespace Surge::Paths -{ - -fs::path binaryPath() -{ - Dl_info info; - if (!dladdr(reinterpret_cast(&binaryPath), &info) || !info.dli_fname[0]) - { - // If dladdr(3) returns zero, dlerror(3) won't know why either - throw std::runtime_error{"Failed to retrieve shared object file name"}; - } - return fs::path{info.dli_fname}; -} - -fs::path homePath() -{ - const char *const path = std::getenv("HOME"); - if (!path || !path[0]) - throw std::runtime_error{"The environment variable HOME is unset or empty"}; - return fs::path{path}; -} - -} // namespace Surge::Paths diff --git a/src/platform/windows/Paths.cpp b/src/platform/windows/Paths.cpp deleted file mode 100644 index cc8c476c756..00000000000 --- a/src/platform/windows/Paths.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -** Surge Synthesizer is Free and Open Source Software -** -** Surge is made available under the Gnu General Public License, v3.0 -** https://www.gnu.org/licenses/gpl-3.0.en.html -** -** Copyright 2004-2021 by various individuals as described by the Git transaction log -** -** All source at: https://github.com/surge-synthesizer/surge.git -** -** Surge was a commercial product from 2004-2018, with Copyright and ownership -** in that period held by Claes Johanson at Vember Audio. Claes made Surge -** open source in September 2018. -*/ - -#include "platform/Paths.h" -#include -#include -#include - -namespace -{ - -fs::path knownFolderPath(REFKNOWNFOLDERID rfid) -{ - fs::path path; - PWSTR pathStr{}; - if (::SHGetKnownFolderPath(rfid, 0, nullptr, &pathStr) == S_OK) - path = pathStr; - ::CoTaskMemFree(pathStr); - if (path.empty()) - throw std::runtime_error{"Failed to retrieve known folder path"}; - return path; -} - -} // anonymous namespace - -namespace Surge::Paths -{ - -fs::path binaryPath() -{ - HMODULE hmodule; - if (!::GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - reinterpret_cast(&binaryPath), &hmodule)) - { - throw std::system_error{int(::GetLastError()), std::system_category(), - "Failed to retrieve module handle"}; - } - - for (std::vector buf{MAX_PATH};; buf.resize(buf.size() * 2)) - { - const auto len = ::GetModuleFileNameW(hmodule, &buf[0], buf.size()); - if (!len) - throw std::system_error{int(::GetLastError()), std::system_category(), - "Failed to retrieve module file name"}; - if (len < buf.size()) - return fs::path{&buf[0]}; - } -} - -fs::path homePath() { return knownFolderPath(FOLDERID_Profile); } - -} // namespace Surge::Paths diff --git a/src/surge-xt/gui/overlays/AboutScreen.cpp b/src/surge-xt/gui/overlays/AboutScreen.cpp index 910bdcaa343..e19aab639a3 100644 --- a/src/surge-xt/gui/overlays/AboutScreen.cpp +++ b/src/surge-xt/gui/overlays/AboutScreen.cpp @@ -20,7 +20,7 @@ #include "version.h" #include "RuntimeFont.h" #include "SurgeImage.h" -#include "platform/Paths.h" +#include "sst/plugininfra/paths.h" #include namespace Surge @@ -193,8 +193,8 @@ void AboutScreen::populateData() lowerLeft.emplace_back("", "", ""); - lowerLeft.emplace_back("Executable:", Paths::appPath().u8string(), - Paths::appPath().parent_path().u8string()); + auto apppath = sst::plugininfra::paths::sharedLibraryBinaryPath(); + lowerLeft.emplace_back("Executable:", apppath.u8string(), apppath.parent_path().u8string()); lowerLeft.emplace_back("Factory Data:", storage->datapath.u8string(), storage->datapath.u8string()); lowerLeft.emplace_back("User Data:", storage->userDataPath.u8string(),