openSUSE:打包游戏
Packaging Games 页面包含关于如何使用 openSUSE 构建服务为 openSUSE 和其他系统打包游戏的指南。
除了标准的打包指南之外,在打包游戏时还有一些其他的强烈建议。
软件包分离
- 如果可能,将游戏文件和数据文件分别打包,以减少错误修复更新的大小。如果上游将游戏数据打包在单独的 tarball 中,则必须这样做。
- 在大多数情况下,游戏数据包(关卡、美术作品、声音和音乐)应为
BuildArch: noarch - 数据文件(地图、像素图、声音)应放在
%{_datadir}/%{name},而不是%{_datadir}/games/%{name}。二进制文件应放在%{_bindir},而不是/usr/games。根据 FHS,/usr/share/games和/usr/games的使用是可选的,我们建议不使用它们以保持一致性,以便游戏像所有其他应用程序一样打包。 - 如果您知道版本 1.3.3 的游戏可以使用版本 1.2 或更高版本的游戏数据,则可以使用以下方案
game.spec
Version: 1.3.3 Requires: game-data >= 1.2
game-data.spec
Version: 1.2 Requires: game >= 1.2
常用库
- 对于需要 SDL 的游戏,请在 BuildRequires 中使用
SDL-devel(以及可能其他的,例如SDL_image-devel、SDL_mixer-devel、SDL_net-devel等)。我们的 SDL 库提供这些符号,直接使用libSDL-devel在 Fedora、Mandriva 和较旧的 openSUSE 版本上将不起作用。
文件和权限
- 根据 FHS,高分和运行时配置文件应放在
/var/games/%{name}中。如果软件包只将单个文件放在此位置,则可以将 %{name} 子目录去掉,并将文件直接放在 /var/games 中。 - 游戏的 man 页面应放在第 6 节:
%{_mandir}/man6/,根据 FHS。 - spec 文件组:
Group: Amusements/Games - 桌面文件类别:
Categories=Game;以及 此列表 中的任何适当类别。有关如何正确执行此操作的信息,请参阅 此邮件。 - 必须包含许可证文件以明确法律地位,即使上游不在源代码 tarball 中提供它。
- 例如 xpilot-ng-server 和 wesnoth 提供的游戏服务守护进程必须在其自己的用户 ID 下运行,而不是 'root'、'games' 或任何其他系统用户。
- 所有
%files必须由 root,root 拥有,除了某些共享文件(例如记分牌)以外。 - 如果需要,可以将游戏设置为 setgid 'games',以便允许共享记分牌文件。但仅在必要时,并且应注意在不需要时放弃 setgid 权限。以下示例显示了如何正确放弃 setuid/setgid 权限。但是,setgid 位需要 SUSE 安全团队的先期批准。
/* Keep a global pointer to the scoreboard file. I know, global vars are
* ugly and should be avoided. Your application might do this differently.
* This is just an example.
*/
extern FILE *scoreboard_filehandle;
/*
* Notice that we deal with dropping setgid immediately in main() after opening
* the scoreboard file, and before doing _anything_ else. This minimizes the amount
* of code that is run setuid/setgid.
*/
int main(int argc, char **argv) {
gid_t realgid;
uid_t realuid;
/* Open the scoreboard file. This could be NULL! Users of this
* variable must check before using and not bother writing a
* scoreboard if it is null.
*
* The file is opened with mode "r+" to preserve the existing contents.
* This allows the program to first read the scoreboard and then write
* it out again with new values. Just make sure you don't close() the file
* after reading it or you won't be able to write to it again.
*/
scoreboard_filehandle=fopen(SCOREBOARDFILE, "r+");
/* Figure out who we really are.
*/
realgid = getgid();
realuid = getuid();
/* This is where we drop our setuid/setgid privileges.
*/
if (setresgid(-1, realgid, realgid) != 0) {
perror("Could not drop setgid privileges. Aborting.");
exit(1);
}
if (setresuid(-1, realuid, realuid) != 0) {
perror("Could not drop setuid privileges. Aborting.");
exit(1);
}
/* ...Continue setting up the game... */
未为 Linux/Unix 设计的游戏
有些游戏并非为 Linux/Unix 设计:它们从单个目录运行,并尝试在其中写入。一个好的解决方案是创建一个 bash 包装器,它
- 在用户的 home 目录中创建一个游戏目录
- 用指向 /usr/share/%{name} 下游戏目录中的文件的符号链接填充它
- 进入该目录并运行实际的二进制文件
这样的脚本可能如下所示:
#!/bin/sh GAME_LOCAL_DIR=$HOME/.mygame GAME_DATA_DIR=/usr/share/mygame GAME_EXECUTABLE=/usr/libexec/mygame/mygame mkdir -p $GAME_LOCAL_DIR cd $GAME_LOCAL_DIR for dir in techs data maps tilesets; do ln -snf $GAME_DATA_DIR/$dir $dir done test -d savegames || mkdir savegames test -e mygame.ini || cp $GAME_DATA_DIR/mygame.ini mygame.ini exec $GAME_EXECUTABLE "$@"
OpenGL 包装器
如果游戏需要 3D 加速显卡,则必须使用 DRI 检查包装器,如果 DRI 不可用,它将显示一个错误对话框,解释关于自由软件和 3D 驱动程序的信息,然后退出。您必须执行的操作是
- 添加:
Requires: opengl-games-utils - 添加到
%installln -s opengl-game-wrapper.sh $RPM_BUILD_ROOT%{_bindir}/%{name}-wrapper - 将
%{_bindir}/%{name}-wrapper添加到%files - 将 .desktop 文件 Exec 条目从
%{name} 更改为%{name}-wrapper
这都假设您的主二进制文件名称 == %{name},否则请相应地进行调整。
如果您已经为某种原因有了一个包装器脚本,您可以将 checkDriOk 函数直接合并到您的包装器中,无需执行包装器包装器,请参阅 vegastrike 的 vegastrike-wrapper.sh 文件作为示例。