История изменений
Исправление slovazap, (текущая версия) :
Проприетарщина или СПО? Если первое - делай тяп ляп как бог на душу положит, для уродов это нормально.
А если СПО и/или для людей и/или нормально поддерживающее опакечивание, то так:
бинарник в /usr/local/bin, локали в /usr/local/share/locale, иконки текстурки всякие в /usr/local/share/игра
Да, только надеюсь под /usr/local ты имел в виду ${PREFIX} который задаётся при установке. Да, PREFIX обычно /usr/local по умолчанию.
настройки в ~/.config/игра
Да, если имелось в виду ${XDG_CONFIG_HOME}/игра, где XDG_CONFIG_HOME берётся из окружения, а по умолчанию ~/.config. К слову, save обычно кладут в ${XDG_DATA_HOME}/игра, где XDG_DATA_HOME по умолчаиню ~/.local/share (на винде могут быть другие умолчания).
остальные файлы в /usr/lib/игра
Какие такие остальные файлы? lib, как ни странно место для библиотек или модулей. «Остальные файлы» - в share/игра.
тогда становится непонятно, как бинарник будет находить, где все эти файлы лежат, ведь префикс может отличаться, получается нужно юзать либо относительные директории, что, вроде как, плохое решение, либо ещё что-то.
Обычно ${PREFIX} вкомпиливается на этапе сборки. Особо умные вместо этого лезут в /proc, берут оттуда путь к бинарнику и от него считают остальные пути, но это мгновенно ломается там где нет никаких /proc впомине. При опакечивании эту дурость обычно выпиливают.
Сделать что-то среднее, что будет работать в обеих случаях, задавая директории в скрипте через переменные окружения.
Ну я лично не вижу лучше способа чем при сборке указывать флаг standalone/systemwide, так можно собрать так штуку которая будет запускаться из текущей директории (причём желательно сделать так чтобы это работало и прямо из репозитория), так и системный пакет.
if(STANDALONE)
set(BINDIR "." CACHE STRING "Where to install binaries")
set(DATAROOTDIR "." CACHE STRING "Root directory for data files")
set(DATADIR "data" CACHE STRING "Where to install data files") # если в репозитории данные лежат в data, то это позволит запускать игру прямо из чекаута, что удобно
set(DESKTOPDIR "." CACHE STRING "Where to install .desktop file")
set(DOCSDIR "." CACHE STRING "Where to install documentation")
else()
# нынче правильнее было бы заиспользовать GNUInstallDirs
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE STRING "Where to install binaries")
set(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "Root directory for data files")
set(DATADIR "${DATAROOTDIR}/${CMAKE_PROJECT_NAME}" CACHE STRING "Where to install data files")
set(DESKTOPDIR "${DATAROOTDIR}/applications" CACHE STRING "Where to install .desktop file")
set(DOCSDIR "${DATAROOTDIR}/doc/${CMAKE_PROJECT_NAME}" CACHE STRING "Where to install documentation")
endif()
Понятное дело, путь нужно передать в приложение:
target_compile_definitions(xxx PRIVATE -DDATADIR="${DATADIR}")
Ну и в приложении что-то типа:
std::string datapath(DATAPATH); # передано из системы сборки
std::string confpath;
char* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home != nullptr) {
confpath = xdg_config_home;
} else {
#ifdef WIN32
TCHAR szPath[MAX_PATH];
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath)))
throw std::runtime_error("Windows sux");
confpath = szPath;
#else
confpath = getenv("HOME") + "/.config"
#endif
}
confpath += "/mygame";
Исходная версия slovazap, :
Проприетарщина или СПО? Если первое - делай тяп ляп как бог на душу положит, для уродов это нормально.
А если СПО и/или для людей и/или нормально поддерживающее опакечивание, то так:
бинарник в /usr/local/bin, локали в /usr/local/share/locale, иконки текстурки всякие в /usr/local/share/игра
Да, только надеюсь под /usr/local ты имел в виду ${PREFIX} который задаётся при установке. Да, PREFIX обычно /usr/local по умолчанию.
настройки в ~/.config/игра
Да, если имелось в виду ${XDG_CONFIG_HOME}/игра, где XDG_CONFIG_HOME берётся из окружения, а по умолчанию ~/.config. К слову, save обычно кладут в ${XDG_DATA_HOME}/игра, где XDG_DATA_HOME по умолчаиню ~/.local/share (на винде могут быть другие умолчания).
остальные файлы в /usr/lib/игра
Какие такие остальные файлы? lib, как ни странно место для библиотек или модулей. «Остальные файлы» - в share/игра.
тогда становится непонятно, как бинарник будет находить, где все эти файлы лежат, ведь префикс может отличаться, получается нужно юзать либо относительные директории, что, вроде как, плохое решение, либо ещё что-то.
Обычно ${PREFIX} вкомпиливается на этапе сборки. Особо умные вместо этого лезут в /proc, берут оттуда путь к бинарнику и от него считают остальные пути, но это мгновенно ломается там где нет никаких /proc впомине. При опакечивании эту дурость обычно выпиливают.
Сделать что-то среднее, что будет работать в обеих случаях, задавая директории в скрипте через переменные окружения.
Ну я лично не вижу лучше способа чем при сборке указывать флаг standalone/systemwide, так можно собрать так штуку которая будет запускаться из текущей директории (причём желательно сделать так чтобы это работало и прямо из репозитория), так и системный пакет.
if(STANDALONE)
set(BINDIR "." CACHE STRING "Where to install binaries")
set(DATAROOTDIR "." CACHE STRING "Root directory for data files")
set(DATADIR "data" CACHE STRING "Where to install data files") # если в репозитории данные лежат в data, то это позволит запускать игру прямо из чекаута, что удобно
set(DESKTOPDIR "." CACHE STRING "Where to install .desktop file")
set(DOCSDIR "." CACHE STRING "Where to install documentation")
else()
# нынче правильнее было бы заиспользовать GNUInstallDirs
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE STRING "Where to install binaries")
set(DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "Root directory for data files")
set(DATADIR "${DATAROOTDIR}/${CMAKE_PROJECT_NAME}" CACHE STRING "Where to install data files")
set(DESKTOPDIR "${DATAROOTDIR}/applications" CACHE STRING "Where to install .desktop file")
set(DOCSDIR "${DATAROOTDIR}/doc/${CMAKE_PROJECT_NAME}" CACHE STRING "Where to install documentation")
endif()
Понятное дело, путь нужно передать в приложение:
target_compile_definitions(xxx PRIVATE -DDATADIR="${DATADIR}")
Ну и в приложении что-то типа:
std::string datapath(DATAPATH);
std::string confpath;
char* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home != nullptr) {
confpath = xdg_config_home;
} else {
#ifdef WIN32
TCHAR szPath[MAX_PATH];
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath)))
throw std::runtime_error("Windows sux");
confpath = szPath;
#else
confpath = getenv("HOME") + "/.config"
#endif
}
confpath += "/mygame";