kde-plasma/breeze-gtk: x86 stable wrt bug #613144
[gentoo.git] / eclass / games.eclass
1 # Copyright 1999-2015 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: games.eclass
5 # @MAINTAINER:
6 # Games team <games@gentoo.org>
7 # @BLURB: Standardizing the install of games.
8 # @DESCRIPTION:
9 # This eclass makes sure that games are consistently handled in gentoo.
10 # It installs game files by default in FHS-compatible directories
11 # like /usr/share/games and sets more restrictive permissions in order
12 # to avoid some security bugs.
13 #
14 # The installation directories as well as the user and group files are
15 # installed as can be controlled by the user. See the variables like
16 # GAMES_BINDIR, GAMES_USER etc. below. These are NOT supposed to be set
17 # by ebuilds!
18 #
19 # For a general guide on writing games ebuilds, see:
20 # https://wiki.gentoo.org/wiki/Project:Games/Ebuild_howto
21 #
22 # WARNING: This eclass is DEPRECATED and must not be used by new games
23 # ebuilds, bug #574082. When writing game ebuilds, no specific eclass
24 # is needed. For more details, see the QA team policies page:
25 # https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Policies#Games
26
27
28 if [[ -z ${_GAMES_ECLASS} ]]; then
29 _GAMES_ECLASS=1
30
31 inherit base multilib toolchain-funcs eutils user
32
33 case ${EAPI:-0} in
34         0|1) EXPORT_FUNCTIONS pkg_setup src_compile pkg_preinst pkg_postinst ;;
35         2|3|4|5) EXPORT_FUNCTIONS pkg_setup src_configure src_compile pkg_preinst pkg_postinst ;;
36         *) die "games.eclass is banned in EAPI=${EAPI}, see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Policies#Games" ;;
37 esac
38
39 if [[ ${CATEGORY}/${PN} != "games-misc/games-envd" ]] ; then
40         # environment file
41         RDEPEND="games-misc/games-envd"
42 fi
43
44 # @ECLASS-VARIABLE: GAMES_PREFIX
45 # @DESCRIPTION:
46 # Prefix where to install games, mostly used by GAMES_BINDIR. Games data should
47 # still go into GAMES_DATADIR. May be set by the user.
48 GAMES_PREFIX=${GAMES_PREFIX:-/usr/games}
49
50 # @ECLASS-VARIABLE: GAMES_PREFIX_OPT
51 # @DESCRIPTION:
52 # Prefix where to install precompiled/blob games, usually followed by
53 # package name. May be set by the user.
54 GAMES_PREFIX_OPT=${GAMES_PREFIX_OPT:-/opt}
55
56 # @ECLASS-VARIABLE: GAMES_DATADIR
57 # @DESCRIPTION:
58 # Base directory where to install game data files, usually followed by
59 # package name. May be set by the user.
60 GAMES_DATADIR=${GAMES_DATADIR:-/usr/share/games}
61
62 # @ECLASS-VARIABLE: GAMES_DATADIR_BASE
63 # @DESCRIPTION:
64 # Similar to GAMES_DATADIR, but only used when a package auto appends 'games'
65 # to the path. May be set by the user.
66 GAMES_DATADIR_BASE=${GAMES_DATADIR_BASE:-/usr/share}
67
68 # @ECLASS-VARIABLE: GAMES_SYSCONFDIR
69 # @DESCRIPTION:
70 # Where to install global games configuration files, usually followed by
71 # package name. May be set by the user.
72 GAMES_SYSCONFDIR=${GAMES_SYSCONFDIR:-/etc/games}
73
74 # @ECLASS-VARIABLE: GAMES_STATEDIR
75 # @DESCRIPTION:
76 # Where to install/store global variable game data, usually followed by
77 # package name. May be set by the user.
78 GAMES_STATEDIR=${GAMES_STATEDIR:-/var/games}
79
80 # @ECLASS-VARIABLE: GAMES_LOGDIR
81 # @DESCRIPTION:
82 # Where to store global game log files, usually followed by
83 # package name. May be set by the user.
84 GAMES_LOGDIR=${GAMES_LOGDIR:-/var/log/games}
85
86 # @ECLASS-VARIABLE: GAMES_BINDIR
87 # @DESCRIPTION:
88 # Where to install the game binaries. May be set by the user. This is in PATH.
89 GAMES_BINDIR=${GAMES_BINDIR:-${GAMES_PREFIX}/bin}
90
91 # @ECLASS-VARIABLE: GAMES_ENVD
92 # @INTERNAL
93 # @DESCRIPTION:
94 # The games environment file name which sets games specific LDPATH and PATH.
95 GAMES_ENVD="90games"
96
97 # @ECLASS-VARIABLE: GAMES_USER
98 # @DESCRIPTION:
99 # The USER who owns all game files and usually has write permissions.
100 # May be set by the user.
101 GAMES_USER=${GAMES_USER:-root}
102
103 # @ECLASS-VARIABLE: GAMES_USER_DED
104 # @DESCRIPTION:
105 # The USER who owns all game files related to the dedicated server part
106 # of a package. May be set by the user.
107 GAMES_USER_DED=${GAMES_USER_DED:-games}
108
109 # @ECLASS-VARIABLE: GAMES_GROUP
110 # @DESCRIPTION:
111 # The GROUP that owns all game files and usually does not have
112 # write permissions. May be set by the user.
113 # If you want games world-executable, then you can at least set this variable
114 # to 'users' which is almost the same.
115 GAMES_GROUP=${GAMES_GROUP:-games}
116
117 # @FUNCTION: games_get_libdir
118 # @DESCRIPTION:
119 # Gets the directory where to install games libraries. This is in LDPATH.
120 games_get_libdir() {
121         echo ${GAMES_PREFIX}/$(get_libdir)
122 }
123
124 # @FUNCTION: egamesconf
125 # @USAGE: [<args>...]
126 # @DESCRIPTION:
127 # Games equivalent to 'econf' for autotools based build systems. It passes
128 # the necessary games specific directories automatically.
129 egamesconf() {
130         # handle verbose build log pre-EAPI5
131         local _gamesconf
132         if has "${EAPI:-0}" 0 1 2 3 4 ; then
133                 if grep -q -s disable-silent-rules "${ECONF_SOURCE:-.}"/configure ; then
134                         _gamesconf="--disable-silent-rules"
135                 fi
136         fi
137
138         # bug 493954
139         if grep -q -s datarootdir "${ECONF_SOURCE:-.}"/configure ; then
140                 _gamesconf="${_gamesconf} --datarootdir=/usr/share"
141         fi
142
143         econf \
144                 --prefix="${GAMES_PREFIX}" \
145                 --libdir="$(games_get_libdir)" \
146                 --datadir="${GAMES_DATADIR}" \
147                 --sysconfdir="${GAMES_SYSCONFDIR}" \
148                 --localstatedir="${GAMES_STATEDIR}" \
149                 ${_gamesconf} \
150                 "$@"
151 }
152
153 # @FUNCTION: gameswrapper
154 # @USAGE: <command> [<args>...]
155 # @INTERNAL
156 # @DESCRIPTION:
157 # Wraps an install command like dobin, dolib etc, so that
158 # it has GAMES_PREFIX as prefix.
159 gameswrapper() {
160         # dont want to pollute calling env
161         (
162                 into "${GAMES_PREFIX}"
163                 cmd=$1
164                 shift
165                 ${cmd} "$@"
166         )
167 }
168
169 # @FUNCTION: dogamesbin
170 # @USAGE: <path>...
171 # @DESCRIPTION:
172 # Install one or more games binaries.
173 dogamesbin() { gameswrapper ${FUNCNAME/games} "$@"; }
174
175 # @FUNCTION: dogamessbin
176 # @USAGE: <path>...
177 # @DESCRIPTION:
178 # Install one or more games system binaries.
179 dogamessbin() { gameswrapper ${FUNCNAME/games} "$@"; }
180
181 # @FUNCTION: dogameslib
182 # @USAGE: <path>...
183 # @DESCRIPTION:
184 # Install one or more games libraries.
185 dogameslib() { gameswrapper ${FUNCNAME/games} "$@"; }
186
187 # @FUNCTION: dogameslib.a
188 # @USAGE: <path>...
189 # @DESCRIPTION:
190 # Install one or more static games libraries.
191 dogameslib.a() { gameswrapper ${FUNCNAME/games} "$@"; }
192
193 # @FUNCTION: dogameslib.so
194 # @USAGE: <path>...
195 # @DESCRIPTION:
196 # Install one or more shared games libraries.
197 dogameslib.so() { gameswrapper ${FUNCNAME/games} "$@"; }
198
199 # @FUNCTION: newgamesbin
200 # @USAGE: <path> <newname>
201 # @DESCRIPTION:
202 # Install one games binary with a new name.
203 newgamesbin() { gameswrapper ${FUNCNAME/games} "$@"; }
204
205 # @FUNCTION: newgamessbin
206 # @USAGE: <path> <newname>
207 # @DESCRIPTION:
208 # Install one system games binary with a new name.
209 newgamessbin() { gameswrapper ${FUNCNAME/games} "$@"; }
210
211 # @FUNCTION: games_make_wrapper
212 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
213 # @DESCRIPTION:
214 # Create a shell wrapper script named wrapper in installpath
215 # (defaults to the games bindir) to execute target (default of wrapper) by
216 # first optionally setting LD_LIBRARY_PATH to the colon-delimited
217 # libpaths followed by optionally changing directory to chdir.
218 games_make_wrapper() { gameswrapper ${FUNCNAME/games_} "$@"; }
219
220 # @FUNCTION: gamesowners
221 # @USAGE: [<args excluding owner/group>...] <path>...
222 # @DESCRIPTION:
223 # Run 'chown' with the given args on the given files. Owner and
224 # group are GAMES_USER and GAMES_GROUP and must not be passed
225 # as args.
226 gamesowners() { chown ${GAMES_USER}:${GAMES_GROUP} "$@"; }
227
228 # @FUNCTION: gamesperms
229 # @USAGE: <path>...
230 # @DESCRIPTION:
231 # Run 'chmod' with games specific permissions on the given files.
232 gamesperms() { chmod u+rw,g+r-w,o-rwx "$@"; }
233
234 # @FUNCTION: prepgamesdirs
235 # @DESCRIPTION:
236 # Fix all permissions/owners of files in games related directories,
237 # usually called at the end of src_install().
238 prepgamesdirs() {
239         local dir f mode
240         for dir in \
241                 "${GAMES_PREFIX}" "${GAMES_PREFIX_OPT}" "${GAMES_DATADIR}" \
242                 "${GAMES_SYSCONFDIR}" "${GAMES_STATEDIR}" "$(games_get_libdir)" \
243                 "${GAMES_BINDIR}" "$@"
244         do
245                 [[ ! -d ${D}/${dir} ]] && continue
246                 (
247                         gamesowners -R "${D}/${dir}"
248                         find "${D}/${dir}" -type d -print0 | xargs -0 chmod 750
249                         mode=o-rwx,g+r,g-w
250                         [[ ${dir} = ${GAMES_STATEDIR} ]] && mode=o-rwx,g+r
251                         find "${D}/${dir}" -type f -print0 | xargs -0 chmod $mode
252
253                         # common trees should not be games owned #264872 #537580
254                         fowners root:0 "${dir}"
255                         fperms 755 "${dir}"
256                         if [[ ${dir} == "${GAMES_PREFIX}" \
257                                                 || ${dir} == "${GAMES_PREFIX_OPT}" ]] ; then
258                                 for d in $(get_libdir) bin ; do
259                                         # check if dirs exist to avoid "nonfatal" option
260                                         if [[ -e ${D}/${dir}/${d} ]] ; then
261                                                 fowners root:0 "${dir}/${d}"
262                                                 fperms 755 "${dir}/${d}"
263                                         fi
264                                 done
265                         fi
266                 ) &>/dev/null
267
268                 f=$(find "${D}/${dir}" -perm +4000 -a -uid 0 2>/dev/null)
269                 if [[ -n ${f} ]] ; then
270                         eerror "A game was detected that is setuid root!"
271                         eerror "${f}"
272                         die "refusing to merge a setuid root game"
273                 fi
274         done
275         [[ -d ${D}/${GAMES_BINDIR} ]] || return 0
276         find "${D}/${GAMES_BINDIR}" -maxdepth 1 -type f -exec chmod 750 '{}' \;
277 }
278
279 # @FUNCTION: games_pkg_setup
280 # @DESCRIPTION:
281 # Export some toolchain specific variables and create games related groups
282 # and users. This function is exported as pkg_setup().
283 games_pkg_setup() {
284         tc-export CC CXX LD AR RANLIB
285
286         enewgroup "${GAMES_GROUP}" 35
287         [[ ${GAMES_USER} != "root" ]] \
288                 && enewuser "${GAMES_USER}" 35 -1 "${GAMES_PREFIX}" "${GAMES_GROUP}"
289         [[ ${GAMES_USER_DED} != "root" ]] \
290                 && enewuser "${GAMES_USER_DED}" 36 /bin/bash "${GAMES_PREFIX}" "${GAMES_GROUP}"
291
292         # Dear portage team, we are so sorry.  Lots of love, games team.
293         # See Bug #61680
294         [[ ${USERLAND} != "GNU" ]] && return 0
295         [[ $(egetshell "${GAMES_USER_DED}") == "/bin/false" ]] \
296                 && usermod -s /bin/bash "${GAMES_USER_DED}"
297 }
298
299 # @FUNCTION: games_src_configure
300 # @DESCRIPTION:
301 # Runs egamesconf if there is a configure file.
302 # This function is exported as src_configure().
303 games_src_configure() {
304         [[ -x "${ECONF_SOURCE:-.}"/configure ]] && egamesconf
305 }
306
307 # @FUNCTION: games_src_compile
308 # @DESCRIPTION:
309 # Runs base_src_make(). This function is exported as src_compile().
310 games_src_compile() {
311         case ${EAPI:-0} in
312                 0|1) games_src_configure ;;
313         esac
314         base_src_make
315 }
316
317 # @FUNCTION: games_pkg_preinst
318 # @DESCRIPTION:
319 # Synchronizes GAMES_STATEDIR of the ebuild image with the live filesystem.
320 games_pkg_preinst() {
321         local f
322
323         while read f ; do
324                 if [[ -e ${ROOT}/${GAMES_STATEDIR}/${f} ]] ; then
325                         cp -p \
326                                 "${ROOT}/${GAMES_STATEDIR}/${f}" \
327                                 "${D}/${GAMES_STATEDIR}/${f}" \
328                                 || die "cp failed"
329                         # make the date match the rest of the install
330                         touch "${D}/${GAMES_STATEDIR}/${f}"
331                 fi
332         done < <(find "${D}/${GAMES_STATEDIR}" -type f -printf '%P\n' 2>/dev/null)
333 }
334
335 # @FUNCTION: games_pkg_postinst
336 # @DESCRIPTION:
337 # Prints some warnings and infos, also related to games groups.
338 games_pkg_postinst() {
339         if [[ -z "${GAMES_SHOW_WARNING}" ]] ; then
340                 ewarn "Remember, in order to play games, you have to"
341                 ewarn "be in the '${GAMES_GROUP}' group."
342                 echo
343                 case ${CHOST} in
344                         *-darwin*) ewarn "Just run 'niutil -appendprop / /groups/games users <USER>'";;
345                         *-freebsd*|*-dragonfly*) ewarn "Just run 'pw groupmod ${GAMES_GROUP} -m <USER>'";;
346                         *) ewarn "Just run 'gpasswd -a <USER> ${GAMES_GROUP}', then have <USER> re-login.";;
347                 esac
348                 echo
349                 einfo "For more info about Gentoo gaming in general, see our website:"
350                 einfo "   https://games.gentoo.org/"
351                 echo
352         fi
353 }
354
355 # @FUNCTION: games_ut_unpack
356 # @USAGE: <directory or file to unpack>
357 # @DESCRIPTION:
358 # Unpack .uz2 files for UT2003/UT2004.
359 games_ut_unpack() {
360         local ut_unpack="$1"
361         local f=
362
363         if [[ -z ${ut_unpack} ]] ; then
364                 die "You must provide an argument to games_ut_unpack"
365         fi
366         if [[ -f ${ut_unpack} ]] ; then
367                 uz2unpack "${ut_unpack}" "${ut_unpack%.uz2}" \
368                         || die "uncompressing file ${ut_unpack}"
369         fi
370         if [[ -d ${ut_unpack} ]] ; then
371                 while read f ; do
372                         uz2unpack "${ut_unpack}/${f}" "${ut_unpack}/${f%.uz2}" \
373                                 || die "uncompressing file ${f}"
374                         rm -f "${ut_unpack}/${f}" || die "deleting compressed file ${f}"
375                 done < <(find "${ut_unpack}" -maxdepth 1 -name '*.uz2' -printf '%f\n' 2>/dev/null)
376         fi
377 }
378
379 # @FUNCTION: games_umod_unpack
380 # @USAGE: <file to unpack>
381 # @DESCRIPTION:
382 # Unpacks .umod/.ut2mod/.ut4mod files for UT/UT2003/UT2004.
383 # Don't forget to set 'dir' and 'Ddir'.
384 games_umod_unpack() {
385         local umod=$1
386         mkdir -p "${Ddir}"/System
387         cp "${dir}"/System/{ucc-bin,{Manifest,Def{ault,User}}.ini,{Engine,Core,zlib,ogg,vorbis}.so,{Engine,Core}.int} "${Ddir}"/System
388         cd "${Ddir}"/System
389         UT_DATA_PATH=${Ddir}/System ./ucc-bin umodunpack -x "${S}/${umod}" -nohomedir &> /dev/null \
390                 || die "uncompressing file ${umod}"
391         rm -f "${Ddir}"/System/{ucc-bin,{Manifest,Def{ault,User},User,UT200{3,4}}.ini,{Engine,Core,zlib,ogg,vorbis}.so,{Engine,Core}.int,ucc.log} &>/dev/null \
392                 || die "Removing temporary files"
393 }
394
395 fi