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