5 # Create a MacOSX Installer package for a given GNUstep directory. It does so
6 # by installing the results in a certain directory and then running the
7 # necessary packaging commands.
13 PKG_BUILD_DIR="$PWD/osxpkgbuild"
14 PKG_DIR="$PKG_BUILD_DIR/${PKG_NAME}.pkg"
15 PKG_RSRC_DIR="$PKG_BUILD_DIR/${PKG_NAME}.pkg/Contents/Resources"
17 ROOT_DIR="$PKG_BUILD_DIR/root"
20 PLIST_DT_ID="-//Apple Computer//DTD PLIST 1.0//EN"
21 PLIST_DT_LOC="http://www.apple.com/DTDs/PropertyList-1.0.dtd"
22 INSTALLER_FORMAT_KEY="0.10000000149011612"
24 BACKGROUND_TIFF="../maintenance/package-background.tiff"
25 LICENSE_FILE="../maintenance/License.rtf"
26 WELCOME_FILE="../maintenance/Welcome.rtf"
36 # ****************************** options ******************************
38 # if we set this to 'yes', we get no 'upgrade' button on "reinstalls"
43 # RootAuthorization / AdminAuthorization
44 PKG_AUTHORIZATION=RootAuthorization
47 # ****************************** usage ********************************
51 make-osxpkg.sh <pkgname>
56 # ****************************** validate cmdline args ****************
58 function validateArgs() {
59 if test "x$PKG_NAME" = "x"; then
66 # ****************************** prepare/cleanup tmpfiles *************
68 function prepareTmpDirs() {
69 if test -d $PKG_BUILD_DIR; then
70 echo -n " deleting old builddir: $PKG_BUILD_DIR .."
71 ${SUDO} ${RM_R} $PKG_BUILD_DIR
75 echo -n " preparing temporary builddir .."
76 ${MKDIRS} "${PKG_BUILD_DIR}"
77 ${MKDIRS} "${PKG_DIR}"
78 ${MKDIRS} "${PKG_RSRC_DIR}"
79 ${MKDIRS} "${PKG_RSRC_DIR}/English.lproj"
80 ${MKDIRS} "${ROOT_DIR}"
81 ${MKDIRS} "${ROOT_DIR}/Library/Frameworks"
82 echo ".. done: $PKG_BUILD_DIR."
85 function fixUpPermissions() {
86 echo -n " fixing permissions in builddir (requires sudo) .."
87 ${SUDO} ${CHOWN} -R root "${ROOT_DIR}"
88 ${SUDO} ${CHGRP} -R admin "${ROOT_DIR}"
89 ${SUDO} ${CHMOD} -R 755 "${ROOT_DIR}"
90 ${SUDO} ${CHMOD} u+t "${ROOT_DIR}"
91 ${SUDO} ${CHMOD} u+t "${ROOT_DIR}/Library"
95 function cleanupTmpDirs() {
96 if test -d $PKG_BUILD_DIR; then
97 echo -n " deleting builddir: $PKG_BUILD_DIR .."
104 # ****************************** install ******************************
106 function installIntoTmpDirs() {
107 echo -n " install sources (log in ${PKG_BUILD_DIR}/install.log) .."
108 make -s FRAMEWORK_INSTALL_DIR="${ROOT_DIR}/Library/Frameworks" \
109 shared=yes frameworks=yes install \
110 >${PKG_BUILD_DIR}/install.log 2>&1
115 # ****************************** pax archive **************************
117 function makePaxArchive() {
118 echo -n " gen archive .."
120 pax -w . | gzip -c >${PKG_DIR}/Contents/Archive.pax.gz
122 cd ${PKG_DIR}/Contents/Resources
123 ln -s ../Archive.pax.gz "${PKG_NAME}.pax.gz"
125 echo ".. done: ${PKG_DIR}/Contents/Archive.pax.gz"
129 # ****************************** bom/sizes ****************************
131 function generateBoM() {
132 echo -n " gen BoM file .."
134 mkbom . "${PKG_DIR}/Contents/Archive.bom"
136 cd ${PKG_DIR}/Contents/Resources
137 ln -s ../Archive.bom "${PKG_NAME}.bom"
142 function calcSizes() {
143 echo -n " calculate sizes .."
144 size_uncompressed="`du -sk $ROOT_DIR | cut -f 1`"
145 size_compressed="`du -sk $PKG_DIR | cut -f 1`"
146 numfiles="`find $ROOT_DIR | wc -l`"
147 numfiles="`echo $numfiles - 1 | bc`"
148 echo ".. done (size=${size_compressed}K/${size_uncompressed}K, #$numfiles)."
151 function generateSizes() {
152 echo -n " gen sizes file .."
154 echo "NumFiles $numfiles" >${PKG_DIR}/Contents/Archive.sizes
155 echo "InstalledSize $size_uncompressed" >>${PKG_DIR}/Contents/Archive.sizes
156 echo "CompressedSize $size_compressed" >>${PKG_DIR}/Contents/Archive.sizes
158 cd ${PKG_DIR}/Contents/Resources
159 ln -s ../Archive.sizes "${PKG_NAME}.sizes"
165 # ****************************** info files ***************************
167 function plistWriteString() {
168 echo " <key>$1</key>"
169 echo " <string>$2</string>"
171 function plistWriteInt() {
172 echo " <key>$1</key>"
173 echo " <integer>`echo $2`</integer>"
175 function plistWriteReal() {
176 echo " <key>$1</key>"
177 echo " <real>`echo $2`</real>"
179 function plistWriteDate() {
180 echo " <key>$1</key>"
181 echo " <date>$2</date>"
183 function plistWriteBool() {
184 echo " <key>$1</key>"
189 function genInfoPList() {
190 # http://developer.apple.com/documentation/DeveloperTools/Conceptual/
191 # SoftwareDistribution/Concepts/sd_pkg_flags.html
192 F="${PKG_DIR}/Contents/Info.plist"
193 echo -n " gen Info.plist: $F .."
195 echo >$F "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
196 echo >>$F "<!DOCTYPE plist PUBLIC \"${PLIST_DT_ID}\" \"${PLIST_DT_LOC}\">"
197 echo >>$F "<plist version=\"1.0\">"
200 plistWriteString >>$F CFBundleGetInfoString "${PKG_NAME} ${PKG_VERSION}"
201 plistWriteString >>$F CFBundleIdentifier "org.opengroupware.pkg.${PKG_NAME}"
202 plistWriteString >>$F CFBundleName "${PKG_NAME}"
203 plistWriteString >>$F CFBundleShortVersionString "${PKG_VERSION}"
205 plistWriteString >>$F IFMajorVersion 4
206 plistWriteString >>$F IFMinorVersion 5
208 plistWriteDate >>$F IFPkgBuildDate "`date -u +%Y-%m-%dT%H:%M:%SZ`"
209 plistWriteString >>$F IFPkgBuildVersion "${PKG_VERSION}"
210 plistWriteBool >>$F IFPkgFlagAllowBackRev true
212 # allowed: AdminAuthorization, RootAuthorization, ??
213 plistWriteString >>$F IFPkgFlagAuthorizationAction ${PKG_AUTHORIZATION}
215 plistWriteString >>$F IFPkgFlagBackgroundAlignment topright
216 plistWriteString >>$F IFPkgFlagBackgroundScaling none
217 plistWriteString >>$F IFPkgFlagDefaultLocation /
218 plistWriteBool >>$F IFPkgFlagFollowLinks true
220 if test "x${PKG_INSTALLFAT}" = "xyes"; then
221 plistWriteBool >>$F IFPkgFlagInstallFat true
223 plistWriteBool >>$F IFPkgFlagInstallFat false
226 plistWriteInt >>$F IFPkgFlagInstalledSize $size_uncompressed
227 plistWriteBool >>$F IFPkgFlagIsRequired false
228 plistWriteBool >>$F IFPkgFlagOverwritePermissions false
230 if test "x${PKG_IS_RELOCATABLE}" = "xyes"; then
231 plistWriteBool >>$F IFPkgFlagRelocatable true
233 plistWriteBool >>$F IFPkgFlagRelocatable false
236 plistWriteString >>$F IFPkgFlagRestartAction NoRestart
237 plistWriteBool >>$F IFPkgFlagRootVolumeOnly false
238 plistWriteBool >>$F IFPkgFlagUpdateInstalledLanguages false
239 plistWriteBool >>$F IFPkgFlagUseUserMask false
240 plistWriteReal >>$F IFPkgFormatVersion "${INSTALLER_FORMAT_KEY}"
241 plistWriteInt >>$F IFPkgPayloadFileCount $numfiles
245 if test "x$CHECK_XML" = "xyes"; then
253 function genBundleVersions() {
254 F="${PKG_RSRC_DIR}/BundleVersions.plist"
255 echo " gen bundle versions: $F .."
257 echo >$F "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
258 echo >>$F "<!DOCTYPE plist PUBLIC \"${PLIST_DT_ID}\" \"${PLIST_DT_LOC}\">"
259 echo >>$F "<plist version=\"1.0\">"
263 frameworks=`find "${ROOT_DIR}" -type d -name "*.framework"`
264 for frameworkpath in $frameworks; do
265 frameworkvfile="`find $frameworkpath -type f -name Version | head -n 1`"
266 if test "x$frameworkvfile" != "x"; then
267 relfwpath="`echo $frameworkpath | sed sX${ROOT_DIR}/XXg`"
269 echo >>$F " <key>${relfwpath}</key>"
271 echo >>$F " <key>BuildVersion</key>"
272 echo >>$F " <string>1</string>" # TODO
273 echo >>$F " <key>CFBundleShortVersionString</key>"
274 echo >>$F " <string>${PKG_VERSION}</string>"
275 echo >>$F " <key>ProjectName</key>"
276 echo >>$F " <string>`basename -s .framework $relfwpath`</string>"
277 echo >>$F " <key>SourceVersion</key>"
278 echo >>$F " <string>${PKG_VERSION}</string>" # TODO
281 echo " Note: no Version file in framework `basename $frameworkpath`"
287 if test "x$CHECK_XML" = "xyes"; then
290 echo " generated: $F."
293 function genEnDescription() {
294 F="${PKG_RSRC_DIR}/English.lproj/Description.plist"
295 echo -n " gen description plist: $F .."
297 echo >$F "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
298 echo >>$F "<!DOCTYPE plist PUBLIC \"${PLIST_DT_ID}\" \"${PLIST_DT_LOC}\">"
299 echo >>$F "<plist version=\"1.0\">"
302 plistWriteString >>$F IFPkgDescriptionDescription "${PKG_NAME}"
303 plistWriteString >>$F IFPkgDescriptionTitle "${PKG_NAME}"
304 plistWriteString >>$F IFPkgDescriptionVersion "${PKG_VERSION}"
308 if test "x$CHECK_XML" = "xyes"; then
314 function genInfoFile() {
315 F="${PKG_RSRC_DIR}/English.lproj/${PKG_NAME}.info"
316 echo -n " gen info file: $F .."
318 echo >$F "Title ${PKG_NAME}"
319 echo >>$F "Version ${PKG_VERSION}"
320 echo >>$F "Description ${PKG_VERSION}"
322 echo >>$F "Require Reboot NO" # TODO: consolidate
323 echo >>$F "OverwritePermissions NO" # TODO: consolidate
324 echo >>$F "UseUserMask NO" # TODO: consolidate
325 echo >>$F "RootVolumeOnly NO" # TODO: consolidate
327 if test "x${PKG_AUTHORIZATION}" = "x"; then
328 echo >>$F "NeedsAuthorization NO"
330 # need to check Admin/Root?
331 echo >>$F "NeedsAuthorization YES"
334 echo >>$F "DefaultLocation /" # TODO: consolidate
336 if test "x${PKG_IS_RELOCATABLE}" = "xyes"; then
337 echo >>$F "Relocatable YES"
339 echo >>$F "Relocatable NO"
342 if test "x${PKG_INSTALLFAT}" = "xyes"; then
343 echo >>$F "Install Fat YES"
345 echo >>$F "Install Fat NO"
348 echo >>$F "LibrarySubdirectory Standard"
353 function genPkgInfoFile() {
354 F="${PKG_DIR}/Contents/PkgInfo"
355 echo -n " gen PkgInfo: $F .."
360 function genPkgVersionFile() {
361 F="${PKG_RSRC_DIR}/package_version"
362 echo -n " gen package_version: $F .."
369 # ****************************** resources ****************************
371 function copyBackgroundImage() {
372 if test -f "${BACKGROUND_TIFF}"; then
373 cp "${BACKGROUND_TIFF}" "${PKG_RSRC_DIR}/background.tiff"
375 echo "ERROR: did not find background image: ${BACKGROUND_TIFF}"
379 function copyLicenseFile() {
380 if test -f "${LICENSE_FILE}"; then
381 cp "${LICENSE_FILE}" "${PKG_RSRC_DIR}/English.lproj/License.rtf"
383 echo "ERROR: did not find file: ${LICENSE_FILE}"
386 function copyWelcomeFile() {
387 if test -f "${WELCOME_FILE}"; then
388 cp "${WELCOME_FILE}" "${PKG_RSRC_DIR}/English.lproj/Welcome.rtf"
390 echo "ERROR: did not find file: ${WELCOME_FILE}"
395 # ****************************** debugging ****************************
397 function debugShowResults() {
399 echo "prepared contents:"
400 find -s $PKG_BUILD_DIR \
401 | sed "sX${PKG_BUILD_DIR}/X Xg"
405 # ****************************** sudo *********************************
407 function ensureSudo() {
408 # this will bring up the 'sudo' authentication
409 if test "x$USER" != "xroot"; then
410 echo "We need to run some commands using 'sudo', so please enter your "
411 echo "credentials when being asked for them (unless you already did so)"
412 sudo touch /tmp/osx-pkg-sudo-tmp
413 sudo rm /tmp/osx-pkg-sudo-tmp
418 # ****************************** running ******************************
420 echo "Building MacOSX Installer.app package $PKG_NAME.pkg .."
447 # debugging, print results
452 if test -d "$PKG_DIR"; then
453 if test -d "${oldpwd}/${PKG_NAME}.pkg"; then
454 rm -rf "${oldpwd}/${PKG_NAME}.pkg"
456 mv "$PKG_DIR" "${oldpwd}/${PKG_NAME}.pkg"
458 echo "ERROR: did not find package: $PKG_DIR"