LINUX.ORG.RU

История изменений

Исправление 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";