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