You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
9.4KB

  1. #!/bin/bash
  2. # Let's make the user give us a target to work with.
  3. # architecture is assumed universal if not specified, and is optional.
  4. # if arch is defined, it we will store the .app bundle in the target arch build directory
  5. if [ $# == 0 ] || [ $# -gt 2 ]; then
  6. echo "Usage: $0 target <arch>"
  7. echo "Example: $0 release x86"
  8. echo "Valid targets are:"
  9. echo " release"
  10. echo " debug"
  11. echo
  12. echo "Optional architectures are:"
  13. echo " x86"
  14. echo " x86_64"
  15. echo " ppc"
  16. echo
  17. exit 1
  18. fi
  19. # validate target name
  20. if [ "$1" == "release" ]; then
  21. TARGET_NAME="release"
  22. elif [ "$1" == "debug" ]; then
  23. TARGET_NAME="debug"
  24. else
  25. echo "Invalid target: $1"
  26. echo "Valid targets are:"
  27. echo " release"
  28. echo " debug"
  29. exit 1
  30. fi
  31. CURRENT_ARCH=""
  32. # validate the architecture if it was specified
  33. if [ "$2" != "" ]; then
  34. if [ "$2" == "x86" ]; then
  35. CURRENT_ARCH="x86"
  36. elif [ "$2" == "x86_64" ]; then
  37. CURRENT_ARCH="x86_64"
  38. elif [ "$2" == "ppc" ]; then
  39. CURRENT_ARCH="ppc"
  40. else
  41. echo "Invalid architecture: $2"
  42. echo "Valid architectures are:"
  43. echo " x86"
  44. echo " x86_64"
  45. echo " ppc"
  46. echo
  47. exit 1
  48. fi
  49. fi
  50. # symlinkArch() creates a symlink with the architecture suffix.
  51. # meant for universal binaries, but also handles the way this script generates
  52. # application bundles for a single architecture as well.
  53. function symlinkArch()
  54. {
  55. EXT="dylib"
  56. SEP="${3}"
  57. SRCFILE="${1}"
  58. DSTFILE="${2}${SEP}"
  59. DSTPATH="${4}"
  60. if [ ! -e "${DSTPATH}/${SRCFILE}.${EXT}" ]; then
  61. echo "**** ERROR: missing ${SRCFILE}.${EXT} from ${MACOS}"
  62. exit 1
  63. fi
  64. if [ ! -d "${DSTPATH}" ]; then
  65. echo "**** ERROR: path not found ${DSTPATH}"
  66. exit 1
  67. fi
  68. pushd "${DSTPATH}" > /dev/null
  69. IS32=`file "${SRCFILE}.${EXT}" | grep "i386"`
  70. IS64=`file "${SRCFILE}.${EXT}" | grep "x86_64"`
  71. ISPPC=`file "${SRCFILE}.${EXT}" | grep "ppc"`
  72. if [ "${IS32}" != "" ]; then
  73. if [ ! -L "${DSTFILE}x86.${EXT}" ]; then
  74. ln -s "${SRCFILE}.${EXT}" "${DSTFILE}x86.${EXT}"
  75. fi
  76. elif [ -L "${DSTFILE}x86.${EXT}" ]; then
  77. rm "${DSTFILE}x86.${EXT}"
  78. fi
  79. if [ "${IS64}" != "" ]; then
  80. if [ ! -L "${DSTFILE}x86_64.${EXT}" ]; then
  81. ln -s "${SRCFILE}.${EXT}" "${DSTFILE}x86_64.${EXT}"
  82. fi
  83. elif [ -L "${DSTFILE}x86_64.${EXT}" ]; then
  84. rm "${DSTFILE}x86_64.${EXT}"
  85. fi
  86. if [ "${ISPPC}" != "" ]; then
  87. if [ ! -L "${DSTFILE}ppc.${EXT}" ]; then
  88. ln -s "${SRCFILE}.${EXT}" "${DSTFILE}ppc.${EXT}"
  89. fi
  90. elif [ -L "${DSTFILE}ppc.${EXT}" ]; then
  91. rm "${DSTFILE}ppc.${EXT}"
  92. fi
  93. popd > /dev/null
  94. }
  95. SEARCH_ARCHS=" \
  96. x86 \
  97. x86_64 \
  98. ppc \
  99. "
  100. HAS_LIPO=`command -v lipo`
  101. HAS_CP=`command -v cp`
  102. # if lipo is not available, we cannot make a universal binary, print a warning
  103. if [ ! -x "${HAS_LIPO}" ] && [ "${CURRENT_ARCH}" == "" ]; then
  104. CURRENT_ARCH=`uname -m`
  105. if [ "${CURRENT_ARCH}" == "i386" ]; then CURRENT_ARCH="x86"; fi
  106. echo "$0 cannot make a universal binary, falling back to architecture ${CURRENT_ARCH}"
  107. fi
  108. # if the optional arch parameter is used, replace SEARCH_ARCHS to only work with one
  109. if [ "${CURRENT_ARCH}" != "" ]; then
  110. SEARCH_ARCHS="${CURRENT_ARCH}"
  111. fi
  112. AVAILABLE_ARCHS=""
  113. IOQ3_VERSION=`grep '^VERSION=' Makefile | sed -e 's/.*=\(.*\)/\1/'`
  114. IOQ3_CLIENT_ARCHS=""
  115. IOQ3_SERVER_ARCHS=""
  116. IOQ3_RENDERER_GL1_ARCHS=""
  117. IOQ3_RENDERER_GL2_ARCHS=""
  118. DEDICATED_NAME="urbanterror-server-m9"
  119. EXECUTABLE_NAME="urbanterror-m9"
  120. RENDERER_OPENGL="renderer_opengl"
  121. RENDERER_OPENGL1_NAME="${RENDERER_OPENGL}1.dylib"
  122. RENDERER_OPENGL2_NAME="${RENDERER_OPENGL}2.dylib"
  123. ICNSDIR="data"
  124. ICNS="urbanterror.icns"
  125. PKGINFO="APPLIOQ3URT"
  126. OBJROOT="build"
  127. #BUILT_PRODUCTS_DIR="${OBJROOT}/${TARGET_NAME}-darwin-${CURRENT_ARCH}"
  128. PRODUCT_NAME="ioq3urt-mickael9"
  129. WRAPPER_EXTENSION="app"
  130. WRAPPER_NAME="${PRODUCT_NAME}.${WRAPPER_EXTENSION}"
  131. CONTENTS_FOLDER_PATH="${WRAPPER_NAME}/Contents"
  132. UNLOCALIZED_RESOURCES_FOLDER_PATH="${CONTENTS_FOLDER_PATH}/Resources"
  133. EXECUTABLE_FOLDER_PATH="${CONTENTS_FOLDER_PATH}/MacOS"
  134. # loop through the architectures to build string lists for each universal binary
  135. for ARCH in $SEARCH_ARCHS; do
  136. CURRENT_ARCH=${ARCH}
  137. BUILT_PRODUCTS_DIR="${OBJROOT}/${TARGET_NAME}-darwin-${CURRENT_ARCH}"
  138. IOQ3_CLIENT="${EXECUTABLE_NAME}.${CURRENT_ARCH}"
  139. IOQ3_SERVER="${DEDICATED_NAME}.${CURRENT_ARCH}"
  140. IOQ3_RENDERER_GL1="${RENDERER_OPENGL}1_${CURRENT_ARCH}.dylib"
  141. IOQ3_RENDERER_GL2="${RENDERER_OPENGL}2_${CURRENT_ARCH}.dylib"
  142. if [ ! -d ${BUILT_PRODUCTS_DIR} ]; then
  143. CURRENT_ARCH=""
  144. BUILT_PRODUCTS_DIR=""
  145. continue
  146. fi
  147. # executables
  148. if [ -e ${BUILT_PRODUCTS_DIR}/${IOQ3_CLIENT} ]; then
  149. IOQ3_CLIENT_ARCHS="${BUILT_PRODUCTS_DIR}/${IOQ3_CLIENT} ${IOQ3_CLIENT_ARCHS}"
  150. VALID_ARCHS="${ARCH} ${VALID_ARCHS}"
  151. else
  152. continue
  153. fi
  154. if [ -e ${BUILT_PRODUCTS_DIR}/${IOQ3_SERVER} ]; then
  155. IOQ3_SERVER_ARCHS="${BUILT_PRODUCTS_DIR}/${IOQ3_SERVER} ${IOQ3_SERVER_ARCHS}"
  156. fi
  157. # renderers
  158. if [ -e ${BUILT_PRODUCTS_DIR}/${IOQ3_RENDERER_GL1} ]; then
  159. IOQ3_RENDERER_GL1_ARCHS="${BUILT_PRODUCTS_DIR}/${IOQ3_RENDERER_GL1} ${IOQ3_RENDERER_GL1_ARCHS}"
  160. fi
  161. if [ -e ${BUILT_PRODUCTS_DIR}/${IOQ3_RENDERER_GL2} ]; then
  162. IOQ3_RENDERER_GL2_ARCHS="${BUILT_PRODUCTS_DIR}/${IOQ3_RENDERER_GL2} ${IOQ3_RENDERER_GL2_ARCHS}"
  163. fi
  164. #echo "valid arch: ${ARCH}"
  165. done
  166. # final preparations and checks before attempting to make the application bundle
  167. cd `dirname $0`
  168. if [ ! -f Makefile ]; then
  169. echo "$0 must be run from the ioquake3 build directory"
  170. exit 1
  171. fi
  172. if [ "${IOQ3_CLIENT_ARCHS}" == "" ]; then
  173. echo "$0: no ioquake3 binary architectures were found for target '${TARGET_NAME}'"
  174. exit 1
  175. fi
  176. # set the final application bundle output directory
  177. if [ "${2}" == "" ]; then
  178. BUILT_PRODUCTS_DIR="${OBJROOT}/${TARGET_NAME}-darwin-universal"
  179. if [ ! -d ${BUILT_PRODUCTS_DIR} ]; then
  180. mkdir -p ${BUILT_PRODUCTS_DIR} || exit 1;
  181. fi
  182. else
  183. BUILT_PRODUCTS_DIR="${OBJROOT}/${TARGET_NAME}-darwin-${CURRENT_ARCH}"
  184. fi
  185. BUNDLEBINDIR="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}"
  186. # here we go
  187. echo "Creating bundle '${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}'"
  188. echo "with architectures:"
  189. for ARCH in ${VALID_ARCHS}; do
  190. echo " ${ARCH}"
  191. done
  192. echo ""
  193. # make the application bundle directories
  194. if [ ! -d "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}" ]; then
  195. mkdir -p "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}" || exit 1;
  196. fi
  197. if [ ! -d "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" ]; then
  198. mkdir -p "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" || exit 1;
  199. fi
  200. # copy and generate some application bundle resources
  201. cp libs/macosx/*.dylib "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}"
  202. cp ${ICNSDIR}/${ICNS} "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/$ICNS" || exit 1;
  203. echo -n ${PKGINFO} > "${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/PkgInfo" || exit 1;
  204. # create Info.Plist
  205. PLIST="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  206. <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
  207. <plist version=\"1.0\">
  208. <dict>
  209. <key>CFBundleDevelopmentRegion</key>
  210. <string>en</string>
  211. <key>CFBundleExecutable</key>
  212. <string>${EXECUTABLE_NAME}</string>
  213. <key>CFBundleIconFile</key>
  214. <string>${ICNS%.icns}</string>
  215. <key>CFBundleIdentifier</key>
  216. <string>org.ioquake.${PRODUCT_NAME}</string>
  217. <key>CFBundleInfoDictionaryVersion</key>
  218. <string>6.0</string>
  219. <key>CFBundleName</key>
  220. <string>${PRODUCT_NAME}</string>
  221. <key>CFBundlePackageType</key>
  222. <string>APPL</string>
  223. <key>CFBundleShortVersionString</key>
  224. <string>${IOQ3_VERSION}</string>
  225. <key>CFBundleSignature</key>
  226. <string>????</string>
  227. <key>CFBundleVersion</key>
  228. <string>${IOQ3_VERSION}</string>
  229. <key>CGDisableCoalescedUpdates</key>
  230. <true/>
  231. <key>NSHumanReadableCopyright</key>
  232. <string>QUAKE III ARENA Copyright © 1999-2000 id Software, Inc. All rights reserved.</string>
  233. <key>NSPrincipalClass</key>
  234. <string>NSApplication</string>
  235. <key>NSHighResolutionCapable</key>
  236. <false/>
  237. </dict>
  238. </plist>
  239. "
  240. echo -e "${PLIST}" > "${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/Info.plist"
  241. # action takes care of generating universal binaries if lipo is available
  242. # otherwise, it falls back to using a simple copy, expecting the first item in
  243. # the second parameter list to be the desired architecture
  244. function action()
  245. {
  246. COMMAND=""
  247. if [ -x "${HAS_LIPO}" ]; then
  248. COMMAND="${HAS_LIPO} -create -o"
  249. $HAS_LIPO -create -o "${1}" ${2} # make sure $2 is treated as a list of files
  250. elif [ -x ${HAS_CP} ]; then
  251. COMMAND="${HAS_CP}"
  252. SRC="${2// */}" # in case there is a list here, use only the first item
  253. $HAS_CP "${SRC}" "${1}"
  254. else
  255. "$0 cannot create an application bundle."
  256. exit 1
  257. fi
  258. #echo "${COMMAND}" "${1}" "${2}"
  259. }
  260. #
  261. # the meat of universal binary creation
  262. # destination file names do not have architecture suffix.
  263. # action will handle merging universal binaries if supported.
  264. # symlink appropriate architecture names for universal (fat) binary support.
  265. #
  266. # executables
  267. action "${BUNDLEBINDIR}/${EXECUTABLE_NAME}" "${IOQ3_CLIENT_ARCHS}"
  268. action "${BUNDLEBINDIR}/${DEDICATED_NAME}" "${IOQ3_SERVER_ARCHS}"
  269. # renderers
  270. action "${BUNDLEBINDIR}/${RENDERER_OPENGL1_NAME}" "${IOQ3_RENDERER_GL1_ARCHS}"
  271. action "${BUNDLEBINDIR}/${RENDERER_OPENGL2_NAME}" "${IOQ3_RENDERER_GL2_ARCHS}"
  272. symlinkArch "${RENDERER_OPENGL}1" "${RENDERER_OPENGL}1" "_" "${BUNDLEBINDIR}"
  273. symlinkArch "${RENDERER_OPENGL}2" "${RENDERER_OPENGL}2" "_" "${BUNDLEBINDIR}"
  274. cd "${BUILT_PRODUCTS_DIR}"
  275. zip --symlinks -r9 "../${BUILT_PRODUCTS_DIR##*/}.zip" ${WRAPPER_NAME}