]> git.lyx.org Git - features.git/blob - development/LyX-Mac-binary-release.sh
do not strip binary for packaging by default; improved name of disk image
[features.git] / development / LyX-Mac-binary-release.sh
1 #!/bin/sh
2
3 # set -x
4
5 # This script automates creating universal binaries of LyX on Mac.
6 # Author: Bennett Helm (and extended by Konrad Hofbauer)
7 # latest changes by Stephan Witt
8 # Last modified: January 2013
9
10 Qt4API=${Qt4API:-"-cocoa"}
11 Qt4Version=${Qt4Version:-"4.6.3"}
12 Qt4SourceVersion="qt-everywhere-opensource-src-${Qt4Version}"
13 Qt4BuildSubDir="qt-${Qt4Version}-build${Qt4API}"
14 Qt4ConfigureOptions=${Qt4ConfigureOptions:-"-release"}
15
16 GettextVersion=${GettextVersion:-"0.18.2"}
17 GettextSource="gettext-${GettextVersion}"
18 GettextLibrary="libintl.8.dylib"
19
20 ASpellVersion=${ASpellVersion:-"0.60.6.1"}
21 ASpellSource="aspell-${ASpellVersion}"
22 ASpellLibrary="libaspell.15.dylib"
23
24 HunSpellVersion=${HunSpellVersion:-"1.3.2"}
25 HunSpellSource="hunspell-${HunSpellVersion}"
26 HunSpellLibrary="libhunspell-1.3.0.dylib"
27
28 unset DYLD_LIBRARY_PATH LD_LIBRARY_PATH
29
30 # Prerequisite:
31 # * a decent checkout of LyX sources (probably you have it already)
32 # * Qt4 - build with shared or static libraries for the used platforms (default: i386 and ppc)
33 #    or - an unpacked source tree of Qt4 in $QT4SOURCEDIR or in the sibling directory (variable Qt4SourceVersion)
34 # * for aspell support:
35 #   the aspell sources placed in a sibling directory (variable ASpellSource)
36 # * for hunspell support:
37 #   the hunspell sources placed in a sibling directory (variable HunSpellSource)
38 # * for dictionary deployment (per default thesauri only):
39 #   - aspell:   the dictionary files of macports (in /opt/local/share/aspell and /opt/local/lib/aspell-0.60)
40 #   - hunspell: the dictionary files in the sibling directory dictionaries/dicts
41 #   - mythes:   the data and idx files in the sibling directory dictionaries/thes
42
43 LyXConfigureOptions="--enable-warnings --enable-optimization=-Os --with-x=no"
44 LyXConfigureOptions="${LyXConfigureOptions} --disable-stdlib-debug"
45 AspellConfigureOptions="--enable-warnings --enable-optimization=-O0 --enable-debug --disable-nls --enable-compile-in-filters --disable-pspell-compatibility"
46 HunspellConfigureOptions="--with-warnings --disable-nls --disable-static"
47 Qt4ConfigureOptions="${QtConfigureOptions} -opensource -silent -shared -fast -no-exceptions"
48 Qt4ConfigureOptions="${Qt4ConfigureOptions} -no-webkit -no-qt3support -no-javascript-jit -no-dbus"
49 Qt4ConfigureOptions="${Qt4ConfigureOptions} -nomake examples -nomake demos -nomake docs -nomake tools"
50 QtMajorVersion=qt4
51
52 # stupid special case...
53 case "${Qt4Version}:${Qt4API}" in
54 4.6*:-carbon)
55         ;;
56 5.0*)
57         Qt4ConfigureOptions="${QtConfigureOptions} -opensource -silent -shared -fast -no-strip"
58         Qt4ConfigureOptions="${Qt4ConfigureOptions} -no-javascript-jit -no-pkg-config"
59         Qt4ConfigureOptions="${Qt4ConfigureOptions} -nomake examples -nomake demos -nomake docs -nomake tools"
60         QtMajorVersion=qt5
61         ;;
62 5.*)
63         QtMajorVersion=qt5
64         ;;
65 *)
66         Qt4ConfigureOptions="${Qt4ConfigureOptions} ${Qt4API}"
67         ;;
68 esac
69
70 aspell_dictionaries="no"
71 hunspell_dictionaries="yes"
72
73 gettext_deployment="no"
74 aspell_deployment="yes"
75 hunspell_deployment="yes"
76 thesaurus_deployment="yes"
77
78 qt4_deployment="yes"
79
80 # auto detect Xcode location
81 if [ -d "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" ]; then
82         DEVELOPER_SDKS="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs"
83         XCODE_DEVELOPER="/Applications/Xcode.app/Contents/Developer"
84         MACOSX_DEPLOYMENT_TARGET="10.7" # Lion support is default
85         SDKROOT="${DEVELOPER_SDKS}/MacOSX10.7.sdk" # Lion build is default
86 elif [ -d "/Developer/SDKs" ]; then
87         DEVELOPER_SDKS="/Developer/SDKs"
88         XCODE_DEVELOPER="/Developer"
89         MACOSX_DEPLOYMENT_TARGET="10.4" # Tiger support is default
90         SDKROOT="${DEVELOPER_SDKS}/MacOSX10.5.sdk" # Leopard build is default
91 fi
92
93 # detection of script home
94 LyxSourceDir=$(dirname "$0")
95 if [ ! -d "${LyxSourceDir}" ]; then
96         echo Missing LyX source directory.
97         exit 2
98 fi
99 case "${LyxSourceDir}" in
100 /*/development)
101         LyxSourceDir=$(dirname "${LyxSourceDir}")
102         ;;
103 /*)
104         ;;
105 */development|development)
106         LyxSourceDir=$(dirname "${LyxSourceDir}")
107         LyxSourceDir=$(cd "${LyxSourceDir}";pwd)
108         ;;
109 *)
110         LyxSourceDir=$(cd "${LyxSourceDir}";pwd)
111         ;;
112 esac
113
114 usage() {
115         echo "*" Build script for LyX on Mac OS X
116         echo
117         echo Optional arguments:
118         echo " --aspell-deployment=yes|no ." default yes
119         echo " --with-qt4-frameworks=yes|no" default no
120         echo " --qt4-deployment=yes|no ...." default yes
121         echo " --with-macosx-target=TARGET " default 10.4 "(Tiger)"
122         echo " --with-sdkroot=SDKROOT ....." default 10.5 "(Leopard)"
123         echo " --with-arch=ARCH ..........." default ppc,i386
124         echo " --with-build-path=PATH ....." default \${lyx-src-dir}/../lyx-build
125         echo " --with-dmg-location=PATH ..." default \${build-path}
126         echo " --with-binary-strip=yes ...." default no
127         echo
128         echo "All other arguments with -- are passed to configure"
129         echo "including the defaults: ${LyXConfigureOptions}"
130         case "${1}" in
131         --help=short)
132                 ;;
133         *)
134                 if [ -x "${LyxSourceDir}/configure" ]; then
135                         echo
136                         echo "*" Configure options of LyX
137                         echo
138                         "${LyxSourceDir}/configure" --help
139                 fi
140         esac
141         exit 0
142 }
143
144 NCPU=$(sysctl -n hw.ncpu)
145 NCPU=$((NCPU / 2))
146 if [ $NCPU -gt 1 ]; then
147         MAKEJOBS=-j${NCPU}
148 fi
149
150 while [ $# -gt 0 ]; do
151         case "${1}" in
152         --with-qt4-frameworks=*)
153                 configure_qt4_frameworks=$(echo ${1}|cut -d= -f2)
154                 if [ "$configure_qt4_frameworks" = "yes" ]; then
155                         unset QTDIR
156                         qt4_deployment="no"
157                 fi
158                 shift
159                 ;;
160         --with-qt4-dir=*)
161                 QTDIR=$(echo ${1}|cut -d= -f2)
162                 shift
163                 ;;
164         --with-macosx-target=*)
165                 MACOSX_DEPLOYMENT_TARGET=$(echo ${1}|cut -d= -f2)
166                 shift
167                 ;;
168         --with-sdkroot=*)
169                 SDKROOT=$(echo ${1}|cut -d= -f2)
170                 case "${SDKROOT}" in
171                 10.4)
172                         SDKROOT="${DEVELOPER_SDKS}/MacOSX10.4u.sdk"
173                         export CC=gcc-4.0
174                         export OBJC=gcc-4.0
175                         export CXX=g++-4.0
176                         ;;
177                 10.5|10.6|10.7|10.8)
178                         SDKROOT="${DEVELOPER_SDKS}/MacOSX${SDKROOT}.sdk"
179                         ;;
180                 *)
181                         usage
182                         ;;
183                 esac
184                 shift
185                 ;;
186         --gettext-deployment=*)
187                 gettext_deployment=$(echo ${1}|cut -d= -f2)
188                 shift
189                 ;;
190         --aspell-deployment=*)
191                 aspell_deployment=$(echo ${1}|cut -d= -f2)
192                 aspell_dictionaries=$aspell_deployment
193                 shift
194                 ;;
195         --hunspell-deployment=*)
196                 hunspell_deployment=$(echo ${1}|cut -d= -f2)
197                 hunspell_dictionaries=$hunspell_deployment
198                 shift
199                 ;;
200         --thesaurus-deployment=*)
201                 thesaurus_deployment=$(echo ${1}|cut -d= -f2)
202                 shift
203                 ;;
204         --qt4-deployment=*)
205                 qt4_deployment=$(echo ${1}|cut -d= -f2)
206                 shift
207                 ;;
208         --with-arch=*)
209                 ARCH=$(echo ${1}|cut -d= -f2|tr ',' ' ')
210                 ARCH_LIST="${ARCH_LIST} ${ARCH}"
211                 shift
212                 ;;
213         --with-dmg-location=*)
214                 DMGLocation=$(echo ${1}|cut -d= -f2)
215                 shift
216                 ;;
217         --with-binary-strip=yes)
218                 strip="-strip"
219                 shift
220                 ;;
221         --with-build-path=*)
222                 LyxBuildDir=$(echo ${1}|cut -d= -f2)
223                 shift
224                 ;;
225         --help|--help=*)
226                 usage "${1}"
227                 ;;
228         --without-aspell)
229                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
230                 aspell_deployment="no"
231                 shift
232                 ;;
233         --without-hunspell)
234                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
235                 hunspell_deployment="no"
236                 shift
237                 ;;
238         --only-package=*)
239                 LyxOnlyPackage=$(echo ${1}|cut -d= -f2)
240                 shift
241                 ;;
242         --*)
243                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
244                 shift
245                 ;;
246         *)
247                 break
248                 ;;
249         esac
250 done
251
252 if [ "${configure_qt4_frameworks}" != "yes" ]; then
253         QtInstallDir=${QTDIR:-"/opt/qt4"}
254 fi
255
256 ARCH_LIST=${ARCH_LIST:-"ppc i386"}
257
258 aspellstrip=
259
260 LyxBuildDir=${LyxBuildDir:-$(dirname "${LyxSourceDir}")/lyx-build}
261 DMGLocation=${DMGLocation:-"${LyxBuildDir}"}
262
263 GettextSourceDir=${GETTEXTDIR:-$(dirname "${LyxSourceDir}")/${GettextSource}}
264 GettextBuildDir="${LyxBuildDir}"/"${GettextSource}"
265 GettextInstallDir=${GettextInstallDir:-"${LyxBuildDir}"/utilities}
266 GettextInstallHdr="${GettextInstallDir}/include/libintl.h"
267
268 ASpellSourceDir=${ASPELLDIR:-$(dirname "${LyxSourceDir}")/${ASpellSource}}
269 ASpellBuildDir="${ASpellSourceDir}"
270 ASpellInstallDir=${ASpellInstallDir:-"${LyxBuildDir}"/utilities}
271 ASpellInstallHdr="${ASpellInstallDir}/include/aspell.h"
272
273 HunSpellSourceDir=${HUNSPELLDIR:-$(dirname "${LyxSourceDir}")/${HunSpellSource}}
274 HunSpellBuildDir="${HunSpellSourceDir}"
275 HunSpellInstallDir=${HunSpellInstallDir:-"${LyxBuildDir}"/utilities}
276 HunSpellInstallHdr="${HunSpellInstallDir}/include/hunspell/hunspell.h"
277
278 Qt4SourceDir=${QT4SOURCEDIR:-$(dirname "${LyxSourceDir}")/${Qt4SourceVersion}}
279 Qt4BuildDir=${Qt4BuildDir:-"${LyxBuildDir}"/${Qt4BuildSubDir:-"qt4-build"}}
280
281 DictionarySourceDir=${DICTIONARYDIR:-$(dirname "${LyxSourceDir}")/dictionaries}
282 DocumentationDir=$(dirname "${LyxSourceDir}")/Documents
283 DmgBackground="${LyxSourceDir}"/development/MacOSX/dmg-background.png
284
285 if [ -z "${LyXVersion}" ]; then
286         LyXVersion=$(grep AC_INIT "${LyxSourceDir}"/configure.ac | cut -d, -f2 | tr -d " ()")
287 fi
288 LyXVersionSuffix=${LyXVersionSuffix:-$(echo "${LyXVersion}" | cut -d. -f1-2)}
289
290 LyxName="LyX"
291 LyxBase="${LyxName}-${LyXVersion}"
292 LyxApp="${LyxBase}.app"
293 LyxAppDir="${LyxBuildDir}"/"${LyxBase}"
294 LyxBuildDir="${LyxAppDir}.build"
295 LyxAppPrefix="${LyxAppDir}.app"
296 # if zip file is needed... remove the comment sign
297 #LyxAppZip="${LyxAppPrefix}.zip"
298
299 # ---------------------------------
300 # DON'T MODIFY ANYTHING BELOW HERE!
301 # ---------------------------------
302
303 # don't change order here...
304 case "${Qt4Version}" in
305 5.0.*|5.1.*)
306         QtLibraries="QtSvg QtXml QtPrintSupport QtWidgets QtGui QtNetwork QtConcurrent QtCore"
307         QtFrameworkVersion="5"
308         ;;
309 5*)
310         QtLibraries="QtSvg QtXml QtPrintSupport QtMacExtras QtWidgets QtGui QtNetwork QtConcurrent QtCore"
311         QtFrameworkVersion="5"
312         ;;
313 *)
314         QtLibraries="QtSvg QtXml QtGui QtNetwork QtCore"
315         QtFrameworkVersion="4"
316         ;;
317 esac
318
319 DMGNAME="${LyxBase}"
320 DMGSIZE="550m"
321
322 # Check for existing SDKs
323 SDKs=$(echo ${DEVELOPER_SDKS}/MacOSX10*sdk)
324 case $SDKs in
325 *${SDKROOT}*)
326         ;;
327 *10.6*)
328         MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"10.5"}; export MACOSX_DEPLOYMENT_TARGET
329         case "${MACOSX_DEPLOYMENT_TARGET}" in
330         10.6)
331                 SDKROOT="${DEVELOPER_SDKS}/MacOSX10.6.sdk"; export SDKROOT
332                 ;;
333         10.5|10.4)
334                 SDKROOT=${SDKROOT:-"${DEVELOPER_SDKS}/MacOSX10.5.sdk"}; export SDKROOT
335                 ;;
336         esac
337         ;;
338 *10.5*)
339         MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"10.4"}; export MACOSX_DEPLOYMENT_TARGET
340         SDKROOT=${SDKROOT:-"${DEVELOPER_SDKS}/MacOSX10.5.sdk"}; export SDKROOT
341         ;;
342 *)
343         echo Unknown or missing SDK for Mac OS X.
344         exit 1
345         ;;
346 esac
347 MYCFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
348
349 # pkg-config is not usable with this script
350 export PKG_CONFIG=""
351
352 # These variables define the identifiers of the
353 # system (both Intel and PowerPC) to compile for.
354 # (Note: darwin8 is 10.4; darwin9 is 10.5.)
355 # Only change these if necessary
356
357 HostSystem_i386="i686-apple-darwin8"
358 HostSystem_ppc="powerpc-apple-darwin8"
359
360 if [ "${configure_qt4_frameworks}" != "yes" -a -d "${Qt4SourceDir}" -a ! \( -d "${Qt4BuildDir}" -a -d "${QtInstallDir}" \) ]; then
361         echo Build Qt4 library ${Qt4SourceDir}
362         if [ "${QtInstallDir}" = "${Qt4BuildDir}" ]; then
363                 echo Bad install directory for Qt.
364                 echo Must be different from build directory "${Qt4BuildDir}".
365                 exit 1
366         fi
367         (
368                 mkdir -p "${Qt4BuildDir}" && cd "${Qt4BuildDir}"
369                 for arch in ${ARCH_LIST} ; do
370                         ARCHS="${ARCHS} -arch ${arch}"
371                 done
372                 echo configure options:
373                 echo ${Qt4ConfigureOptions} ${ARCHS} -prefix "${QtInstallDir}"
374                 echo yes | "${Qt4SourceDir}"/configure ${Qt4ConfigureOptions} ${ARCHS} -prefix "${QtInstallDir}"
375                 make ${MAKEJOBS} && make install
376         )
377         cd "${QtInstallDir}" && (
378                 mkdir -p include
379                 cd include
380                 for libnm in ${QtLibraries} ; do
381                         test -d ${libnm} -o -L ${libnm} || ln -s ../lib/${libnm}.framework/Headers ${libnm}
382                 done
383         )
384 fi
385
386 if [ -d "${GettextSourceDir}" -a ! -f "${GettextInstallHdr}" ]; then
387         # we have a private Gettext source tree at hand...
388         # so let's build and install it
389         if [ -z "${GettextVersion}" ]; then
390                 GettextVersion=$(grep AC_INIT "${GettextSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
391         fi
392
393         GettextName="Gettext"
394         GettextBase="${GettextName}-${GettextVersion}"
395
396         echo Build gettext library ${GettextBase}
397         echo configure options:
398         echo --prefix="${GettextInstallDir}" ${GettextConfigureOptions}
399
400         mkdir -p "${GettextBuildDir}" && cd "${GettextBuildDir}"
401
402         # ----------------------------------------
403         # Build Gettext for different architectures
404         # ----------------------------------------
405         FILE_LIST="${GettextLibrary}"
406
407         for arch in ${ARCH_LIST} ; do
408                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
409                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
410                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
411                 "${GettextSourceDir}/configure"\
412                         --prefix="${GettextInstallDir}"\
413                         ${GettextConfigureOptions}
414                 make && make install${strip}
415                 for file in ${FILE_LIST} ; do
416                         if [ -f "${GettextInstallDir}"/lib/${file} ]; then
417                                 mv "${GettextInstallDir}"/lib/${file}\
418                                         "${GettextInstallDir}"/lib/${file}-${arch} 
419                         else
420                                 echo Cannot build and install Gettext for ${arch}.
421                                 exit 1
422                         fi
423                 done
424         done
425         # -------------------------
426         # Create universal binaries
427         # -------------------------
428         for file in ${FILE_LIST} ; do
429                 OBJ_LIST=
430                 for arch in ${ARCH_LIST} ; do
431                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
432                 done
433                 (
434                         cd "${GettextInstallDir}"
435                         lipo -create ${OBJ_LIST} -o lib/${file}
436                 )
437         done
438         # --------
439         # Clean up
440         # --------
441         for arch in ${ARCH_LIST} ; do
442                 rm -f "${GettextInstallDir}"/lib/*-${arch}
443         done
444 fi
445
446 if [ -d "${HunSpellSourceDir}" -a ! -f "${HunSpellInstallHdr}" ]; then
447         # we have a private HunSpell source tree at hand...
448         # so let's build and install it
449         if [ -z "${HunSpellVersion}" ]; then
450                 HunSpellVersion=$(grep AC_INIT "${HunSpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
451         fi
452
453         HunSpellName="Hunspell"
454         HunSpellBase="${HunSpellName}-${HunSpellVersion}"
455
456         echo Build hunspell library ${HunSpellBase}
457         echo configure options:
458         echo --prefix="${HunSpellInstallDir}" ${HunspellConfigureOptions}
459
460         mkdir -p "${HunSpellBuildDir}" && cd "${HunSpellBuildDir}"
461
462         # ----------------------------------------
463         # Build HunSpell for different architectures
464         # ----------------------------------------
465         FILE_LIST="${HunSpellLibrary}"
466
467         for arch in ${ARCH_LIST} ; do
468                 make distclean
469                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
470                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
471                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
472                 "${HunSpellSourceDir}/configure"\
473                         --prefix="${HunSpellInstallDir}"\
474                         ${HunspellConfigureOptions}
475                 make && make install${strip}
476                 for file in ${FILE_LIST} ; do
477                         if [ -f "${HunSpellInstallDir}"/lib/${file} ]; then
478                                 mv "${HunSpellInstallDir}"/lib/${file}\
479                                         "${HunSpellInstallDir}"/lib/${file}-${arch} 
480                         else
481                                 echo Cannot build and install HunSpell for ${arch}.
482                                 exit 1
483                         fi
484                 done
485         done
486         # -------------------------
487         # Create universal binaries
488         # -------------------------
489         for file in ${FILE_LIST} ; do
490                 OBJ_LIST=
491                 for arch in ${ARCH_LIST} ; do
492                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
493                 done
494                 (
495                         cd "${HunSpellInstallDir}"
496                         lipo -create ${OBJ_LIST} -o lib/${file}
497                         # check for the "missing link"...
498                         test -f lib/libhunspell.dylib || (cd lib ; ln -s "${HunSpellLibrary}" libhunspell.dylib)
499                 )
500         done
501         # --------
502         # Clean up
503         # --------
504         for arch in ${ARCH_LIST} ; do
505                 rm -f "${HunSpellInstallDir}"/lib/*-${arch}
506         done
507 fi
508
509 if [ -d "${ASpellSourceDir}" -a ! -f "${ASpellInstallHdr}" -a "yes" = "${aspell_deployment}" ]; then
510         # we have a private ASpell source tree at hand...
511         # so let's build and install it
512         if [ -z "${ASpellVersion}" ]; then
513                 ASpellVersion=$(grep AC_INIT "${ASpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
514         fi
515
516         ASpellName="Aspell"
517         ASpellBase="${ASpellName}-${ASpellVersion}"
518
519         echo Build aspell library ${ASpellBase}
520         echo configure options:
521         echo --prefix="${ASpellInstallDir}" ${AspellConfigureOptions}
522
523         # ASpell builds inplace only :(
524         cd "${ASpellSourceDir}"
525
526         # ----------------------------------------
527         # Build ASpell for different architectures
528         # ----------------------------------------
529         FILE_LIST="${ASpellLibrary}"
530
531         for arch in ${ARCH_LIST} ; do
532                 make distclean
533                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
534                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
535                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
536                 CXXFLAGS=-g "${ASpellSourceDir}/configure"\
537                         --prefix="${ASpellInstallDir}"\
538                         ${AspellConfigureOptions}
539                 make && make install${aspellstrip}
540                 for file in ${FILE_LIST} ; do
541                         if [ -f "${ASpellInstallDir}"/lib/${file} ]; then
542                                 mv "${ASpellInstallDir}"/lib/${file}\
543                                         "${ASpellInstallDir}"/lib/${file}-${arch} 
544                         else
545                                 echo Cannot build and install ASpell for ${arch}.
546                                 exit 1
547                         fi
548                 done
549         done
550         # -------------------------
551         # Create universal binaries
552         # -------------------------
553         for file in ${FILE_LIST} ; do
554                 OBJ_LIST=
555                 for arch in ${ARCH_LIST} ; do
556                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
557                 done
558                 (
559                         cd "${ASpellInstallDir}"
560                         lipo -create ${OBJ_LIST} -o lib/${file}
561                 )
562         done
563         # --------
564         # Clean up
565         # --------
566         for arch in ${ARCH_LIST} ; do
567                 rm -f "${ASpellInstallDir}"/lib/*-${arch}
568         done
569 fi
570
571
572 framework_name() {
573         echo "Frameworks/${1}.framework"
574 }
575
576 LYX_FILE_LIST="lyx lyxclient tex2lyx"
577 BUNDLE_PATH="Contents/MacOS"
578 LYX_BUNDLE_PATH="${LyxAppPrefix}/${BUNDLE_PATH}"
579 build_lyx() {
580         # Clear Output
581         if [ -n "${LyxAppZip}" -a -f "${LyxAppZip}" ]; then rm "${LyxAppZip}"; fi
582         if [ -d "${LyxAppPrefix}" ]; then rm -rf "${LyxAppPrefix}"; fi
583
584         # -------------------------------------
585         # Automate configure check
586         # -------------------------------------
587         if [ ! -f "${LyxSourceDir}"/configure -o "${LyxSourceDir}"/configure -ot "${LyxSourceDir}"/configure.ac ]; then
588                 ( cd "${LyxSourceDir}" && sh autogen.sh )
589         else
590                 find "${LyxSourceDir}" -name Makefile.am -print | while read file ; do
591                         dname=$(dirname "$file")
592                         if [ -f "$dname/Makefile.in" -a "$dname/Makefile.in" -ot "$file" ]; then
593                                 ( cd "${LyxSourceDir}" && sh autogen.sh )
594                                 break
595                         fi
596                 done
597         fi
598         # -------------------------------------
599         # Build LyX for different architectures
600         # -------------------------------------
601
602         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_deployment}" ]; then
603                 ConfigureExtraInc="--with-extra-inc=${ASpellInstallDir}/include"
604                 ConfigureExtraLib="--with-extra-lib=${ASpellInstallDir}/lib"
605         fi
606
607         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_deployment}" ]; then
608                 HunSpellFramework=$(framework_name Hunspell)
609                 HunSpellFramework=$(basename "${HunSpellFramework}")
610                 ConfigureExtraInc="--with-extra-inc=${HunSpellInstallDir}/include"
611                 ConfigureExtraLib="--with-extra-lib=${HunSpellInstallDir}/lib"
612                 # LyXConfigureOptions="${LyXConfigureOptions} --with-hunspell-framework=${HunSpellFramework}"
613         fi
614         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraInc}"
615         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraLib}"
616
617         for arch in ${ARCH_LIST} ; do
618
619                 if [ -d "${LyxBuildDir}" ];  then rm -r "${LyxBuildDir}"; fi
620                 mkdir -p "${LyxBuildDir}" && cd "${LyxBuildDir}"
621
622                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
623                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
624                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
625
626                 if [ "$configure_qt4_frameworks" = "yes" ]; then
627                         export QT4_CORE_CFLAGS="-FQtCore"
628                         export QT4_CORE_LIBS="-framework QtCore"
629                         export QT4_FRONTEND_CFLAGS="-FQtGui"
630                         export QT4_FRONTEND_LIBS="-framework QtGui"
631                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtCore.framework/Headers"
632                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtGui.framework/Headers"
633                 fi
634
635                 echo LDFLAGS="${LDFLAGS}"
636                 export LDFLAGS
637                 echo CPPFLAGS="${CPPFLAGS}"
638                 export CPPFLAGS
639                 echo CONFIGURE_OPTIONS="${LyXConfigureOptions}" ${QtInstallDir:+"--with-qt4-dir=${QtInstallDir}"}
640                 "${LyxSourceDir}/configure"\
641                         --prefix="${LyxAppPrefix}" --with-version-suffix="-${LyXVersionSuffix}"\
642                         ${QtInstallDir:+"--with-qt4-dir=${QtInstallDir}"} \
643                         ${LyXConfigureOptions}\
644                         --enable-build-type=rel && \
645                 make ${MAKEJOBS} && make install${strip}
646                 for file in ${LYX_FILE_LIST} ; do
647                         if [ -f "${LYX_BUNDLE_PATH}/${file}" ]; then
648                                 mv "${LYX_BUNDLE_PATH}/${file}"\
649                                         "${LYX_BUNDLE_PATH}/${file}-${arch}" 
650                         else
651                                 echo ERROR: Cannot build and install LyX for ${arch}.
652                                 exit 1
653                         fi
654                 done
655         done
656 }
657
658 content_directory() {
659         target="$1"
660         content=$(dirname "${target}")
661         content=$(dirname "${content}")
662         echo "${content}"
663 }
664
665 private_framework() {
666         fwdir=$(framework_name "$1")
667         source="$2"
668         target="$3"
669         condir=$(content_directory "${target}")
670         libnm=$(basename "${source}")
671         mkdir -p "${condir}/${fwdir}"
672         if [ ! -f "${condir}/${fwdir}/${libnm}" ]; then
673                 cp -p "${source}" "${condir}/${fwdir}"
674                 echo Set library id in "${condir}/${fwdir}/${libnm}"
675                 install_name_tool -id "@executable_path/../${fwdir}/${libnm}" "${condir}/${fwdir}/${libnm}"
676         fi
677         echo Correct library id reference to "${libnm}" in "${target}"
678         install_name_tool -change "${source}" "@executable_path/../${fwdir}/${libnm}" "${target}"
679 }
680
681 deploy_qtlibs() {
682         source="${QtInstallDir}"
683         target="$1"
684         version="Versions/${QtFrameworkVersion}/"
685         condir=$(content_directory "${target}")
686         mkdir -p "${condir}/Resources"
687         test -f "${condir}/Resources/qt.conf" || cat - > "${condir}/Resources/qt.conf" <<-EOF
688 [Paths]
689 Plugins = PlugIns
690 Translations = translations
691 EOF
692         if [ ! -d "${condir}/PlugIns" ]; then
693                 mkdir -p "${condir}/PlugIns"
694                 find "${source}/plugins" -name \*.dylib -print | grep -v _debug.dylib | while read libname ; do
695                         echo Copy plugin "${libname}"
696                         dylib=$(basename "${libname}")
697                         dirname=$(dirname "${libname}")
698                         dirname=$(basename "${dirname}")
699                         mkdir -p "${condir}/PlugIns/${dirname}"
700                         cp -p "${libname}" "${condir}/PlugIns/${dirname}"
701                 done
702         fi
703         for libnm in ${QtLibraries} ; do
704                 fwdir=$(framework_name "$libnm")
705                 dirname=$(dirname "${fwdir}")
706                 mkdir -p "${condir}/${dirname}"
707                 dirname=$(basename "${fwdir}")
708                 test -d "${condir}/${fwdir}" || (
709                         echo Copy framework "${source}/lib/"$(basename "${fwdir}")
710                         cp -pR "${source}/lib/"$(basename "${fwdir}") "${condir}/${fwdir}"
711                         echo Set library id in "${condir}/${fwdir}/${version}${libnm}"
712                         install_name_tool -id "@executable_path/../${fwdir}/${version}${libnm}" "${condir}/${fwdir}/${version}${libnm}"
713                         find "${condir}/PlugIns" "${condir}/"$(dirname "${fwdir}") -name Headers -prune -o -type f -print | while read filename ; do
714                                 if [ "${filename}" != "${target}" ]; then
715                                         otool -L "${filename}" 2>/dev/null | sort -u | while read library ; do
716                                                 # pattern match for: /path/to/qt4/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.6.0, current version 4.6.2)
717                                                 case "${library}" in
718                                                 *"${libnm}"*"("*version*")"*)
719                                                         echo Correct library id reference to "${libnm}" in "${filename}"
720                                                         install_name_tool -change\
721                                                                 "${source}/lib/${dirname}/${version}${libnm}"\
722                                                                 "@executable_path/../${fwdir}/${version}${libnm}"\
723                                                                 "${filename}"
724                                                         ;;
725                                                 esac
726                                         done
727                                 fi
728                         done
729                 )
730                 echo Correct library id reference to "${libnm}" in "${target}"
731                 install_name_tool -change\
732                         "${source}/lib/${dirname}/${version}${libnm}"\
733                         "@executable_path/../${fwdir}/${version}${libnm}"\
734                         "${target}"
735         done
736         if [ ! -d "${condir}/translations" ]; then
737                 mkdir -p "${condir}/translations"
738         fi
739         echo Copy Qt translations to "${condir}/translations"
740         cp -p "${source}"/translations/qt_*.qm "${condir}/translations"
741 }
742
743 # -------------------------
744 # Create universal binaries
745 # -------------------------
746 convert_universal() {
747         cd "${LyxAppPrefix}"
748         for file in ${LYX_FILE_LIST} ; do
749                 OBJ_LIST=
750                 for arch in ${ARCH_LIST} ; do
751                         if [ -f "${BUNDLE_PATH}/${file}-${arch}" ]; then
752                                 OBJ_LIST="${OBJ_LIST} ${BUNDLE_PATH}/${file}-${arch}"
753                         fi
754                 done
755                 if [ -n "${OBJ_LIST}" ]; then
756                         lipo -create ${OBJ_LIST} -o "${BUNDLE_PATH}/${file}"
757                 fi
758                 if [ -f "${GettextInstallDir}/lib/${GettextLibrary}" -a "yes" = "${gettext_deployment}" ]; then
759                         private_framework Gettext "${GettextInstallDir}/lib/${GettextLibrary}" "${LYX_BUNDLE_PATH}/${file}"
760                 fi
761                 if [ -f "${ASpellInstallDir}/lib/${ASpellLibrary}" -a "yes" = "${aspell_deployment}" ]; then
762                         private_framework Aspell "${ASpellInstallDir}/lib/${ASpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
763                 fi
764                 if [ -f "${HunSpellInstallDir}/lib/${HunSpellLibrary}" -a "yes" = "${hunspell_deployment}" ]; then
765                         private_framework Hunspell "${HunSpellInstallDir}/lib/${HunSpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
766                 fi
767                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt4_deployment}" ]; then
768                         deploy_qtlibs "${LYX_BUNDLE_PATH}/${file}"
769                 fi
770                 otool -L "${BUNDLE_PATH}/${file}" | while read reference ; do
771                         case "${reference}" in
772                         *"${LyxBuildDir}"*"("*")")
773                                 echo ERROR: Bad reference to "${reference}" found!!
774                                 ;;
775                         esac
776                 done
777         done
778         for arch in ${ARCH_LIST} ; do
779                 rm -f ${BUNDLE_PATH}/*-${arch}
780         done
781 }
782
783 copy_dictionaries() {
784         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_dictionaries}" ]; then
785                 ASpellResources="${LyxAppPrefix}/Contents/Resources"
786                 # try to reuse macports dictionaries for now
787                 if [ -d /opt/local/lib/aspell-0.60 ]; then ASpellInstallDir=/opt/local ; fi
788                 mkdir -p "${ASpellResources}"
789                 echo Copy Aspell dictionaries from "${ASpellInstallDir}"
790                 mkdir -p "${ASpellResources}"/data "${ASpellResources}"/dicts
791                 cp -p -r "${ASpellInstallDir}/lib/aspell-0.60"/* "${ASpellResources}"/data
792                 cp -p -r "${ASpellInstallDir}/share/aspell"/* "${ASpellResources}"/dicts
793         fi
794         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_dictionaries}" ]; then
795                 HunSpellResources="${LyxAppPrefix}/Contents/Resources"
796                 if [ -d "${DictionarySourceDir}" ]; then
797                         ( cd "${DictionarySourceDir}" && find dicts -name .svn -prune -o -type f -print | cpio -pmdv "${HunSpellResources}" )
798                 fi
799         fi
800         if [ -d "${DictionarySourceDir}" -a "yes" = "${thesaurus_deployment}" ]; then
801                 MyThesResources="${LyxAppPrefix}/Contents/Resources"
802                 ( cd "${DictionarySourceDir}" && find thes -name .svn -prune -o -type f -print | cpio -pmdv "${MyThesResources}" )
803         fi
804 }
805
806 set_bundle_display_options() {
807         X_BOUNDS=$2
808         Y_BOUNDS=$3
809         Y_POSITION=$((Y_BOUNDS - 65))
810         Y_BOUNDS=$((Y_BOUNDS + 20))
811         LYX_X_POSITION=$((X_BOUNDS / 4))
812         LYX_Y_POSITION=$Y_POSITION
813         APP_X_POSITION=$((3 * X_BOUNDS / 4))
814         APP_Y_POSITION=$Y_POSITION
815         WITH_DOCUMENTS=$(test -d "${1}/Documents" && echo true || echo false)
816         osascript <<-EOF
817         tell application "Finder"
818         set f to POSIX file ("${1}" as string) as alias
819         tell folder f
820             open
821             tell container window
822                 set toolbar visible to false
823                 set statusbar visible to false
824                 set current view to icon view
825                 delay 1 -- sync
826                 set the bounds to {20, 50, $X_BOUNDS, $Y_BOUNDS}
827             end tell
828             delay 1 -- sync
829             set icon size of the icon view options of container window to 64
830             set arrangement of the icon view options of container window to not arranged
831             if ${WITH_DOCUMENTS} then
832                set position of item "Documents" to {$LYX_X_POSITION,0}
833             end if
834             set position of item "${LyxName}.app" to {$LYX_X_POSITION,$LYX_Y_POSITION}
835             set position of item "Applications" to {$APP_X_POSITION,$APP_Y_POSITION}
836             set background picture of the icon view options\
837                of container window to file "background.png" of folder "Pictures"
838             set the bounds of the container window to {0, 0, $X_BOUNDS, $Y_BOUNDS}
839             update without registering applications
840             delay 5 -- sync
841             close
842         end tell
843         delay 5 -- sync
844     end tell
845 EOF
846 }
847
848 make_dmg() {
849         cd "${1}"
850
851         BGSIZE=$(file "$DmgBackground" | awk -F , '/PNG/{print $2 }' | tr x ' ')
852         BG_W=$(echo ${BGSIZE} | awk '{print $1 }')
853         BG_H=$(echo ${BGSIZE} | awk '{print $2 }')
854
855         rm -f "${DMGNAME}.sparseimage" "${DMGNAME}.dmg"
856
857         hdiutil create -type SPARSE -size ${DMGSIZE:-"250m"} -fs HFS+ -volname "${LyxBase}" "${DMGNAME}"
858         # Unmount currently mounted disk image
859         test -d /Volumes/"${LyxBase}" && umount /Volumes/"${LyxBase}"
860
861         # Mount the disk image
862         hdiutil attach "${DMGNAME}.sparseimage"
863
864         # Obtain device information
865         DEVS=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
866         DEV=$(echo $DEVS | cut -f 1 -d ' ')
867         VOLUME=$(mount |grep ${DEV} | cut -f 3 -d ' ')
868
869         # copy in the application bundle
870         cp -Rp "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
871
872         # copy in background image
873         mkdir -p "${VOLUME}/Pictures"
874         cp "${DmgBackground}" "${VOLUME}/Pictures/background.png"
875         # symlink applications
876         ln -s /Applications/ "${VOLUME}"/Applications
877         test -d "${DocumentationDir}" && cp -r "${DocumentationDir}" "${VOLUME}"
878         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
879         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
880         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
881
882         # Unmount the disk image
883         hdiutil detach ${DEV}
884
885         # Convert the disk image to read-only
886         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
887         rm -f "${DMGNAME}.sparseimage"
888 }
889
890 # ------------------------------
891 # Building distribution packages
892 # ------------------------------
893
894 build_package() {
895         test -n "${LyxAppZip}" && (
896                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
897         )
898
899         DMGARCH=""
900         for arch in ${ARCH_LIST} ; do
901                 DMGARCH="${DMGARCH}-${arch}"
902         done
903         QtDmgArchSuffix=${QtMajorVersion}${DMGARCH}${Qt4API}.dmg
904
905         test -n "${DMGLocation}" && (
906                 make_dmg "${DMGLocation}"
907                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt4_deployment}" ]; then
908                         rm -f "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
909                         echo move to "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
910                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
911                 fi
912         )
913 }
914
915 # ------------------------------
916 # main block
917 # ------------------------------
918
919 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
920         build_lyx
921         convert_universal
922         copy_dictionaries
923 fi
924 build_package