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