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