]> git.lyx.org Git - features.git/blob - development/LyX-Mac-binary-release.sh
9f13ce1b3359feea60f02481af2cf83360ec6ac7
[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 installname() {
682                 echo install_name_tool "$@"
683                 install_name_tool "$@"
684 }
685
686 private_framework() {
687         fwdir=$(framework_name "$1")
688         source="$2"
689         target="$3"
690         condir=$(content_directory "${target}")
691         libnm=$(basename "${source}")
692         mkdir -p "${condir}/${fwdir}"
693         if [ ! -f "${condir}/${fwdir}/${libnm}" ]; then
694                 cp -p "${source}" "${condir}/${fwdir}"
695                 installname -id "@executable_path/../${fwdir}/${libnm}" "${condir}/${fwdir}/${libnm}"
696         fi
697         installname -change "${source}" "@executable_path/../${fwdir}/${libnm}" "${target}"
698 }
699
700 deploy_qtlibs() {
701         source="${QtInstallDir}"
702         target="$1"
703         version="Versions/${QtFrameworkVersion}/"
704         condir=$(content_directory "${target}")
705         mkdir -p "${condir}/Resources"
706         test -f "${condir}/Resources/qt.conf" || cat - > "${condir}/Resources/qt.conf" <<-EOF
707 [Paths]
708 Plugins = PlugIns
709 Translations = translations
710 EOF
711         if [ ! -d "${condir}/PlugIns" ]; then
712                 mkdir -p "${condir}/PlugIns"
713                 find "${source}/plugins" -name \*.dylib -print | grep -v _debug.dylib | while read libname ; do
714                         echo Copy plugin "${libname}"
715                         dylib=$(basename "${libname}")
716                         dirname=$(dirname "${libname}")
717                         dirname=$(basename "${dirname}")
718                         mkdir -p "${condir}/PlugIns/${dirname}"
719                         cp -p "${libname}" "${condir}/PlugIns/${dirname}"
720                 done
721         fi
722         for libnm in ${QtLibraries} ; do
723                 fwdir=$(framework_name "$libnm")
724                 dirname=$(dirname "${fwdir}")
725                 mkdir -p "${condir}/${dirname}"
726                 dirname=$(basename "${fwdir}")
727                 test -d "${condir}/${fwdir}" || (
728                         echo Copy framework "${source}/lib/"$(basename "${fwdir}")
729                         cp -pR "${source}/lib/"$(basename "${fwdir}") "${condir}/${fwdir}"
730                         installname -id "@executable_path/../${fwdir}/${version}${libnm}" "${condir}/${fwdir}/${version}${libnm}"
731                         find "${condir}/PlugIns" "${condir}/"$(dirname "${fwdir}") -name Headers -prune -o -type f -print | while read filename ; do
732                                 if [ "${filename}" != "${target}" ]; then
733                                         otool -L "${filename}" 2>/dev/null | sort -u | while read library ; do
734                                                 # pattern match for: /path/to/qt/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.6.0, current version 4.6.2)
735                                                 case "${library}" in
736                                                 *@rpath/*"${libnm}"*"("*version*")"*)
737                                                         echo rpath based name for ${libnm} is ok.
738                                                         ;;
739                                                 *"${libnm}"*"("*version*")"*)
740                                                         installname -change\
741                                                                 "${source}/lib/${dirname}/${version}${libnm}"\
742                                                                 "@executable_path/../${fwdir}/${version}${libnm}"\
743                                                                 "${filename}"
744                                                         ;;
745                                                 esac
746                                         done
747                                 fi
748                         done
749                 )
750                 installname -change\
751                         "${source}/lib/${dirname}/${version}${libnm}"\
752                         "@executable_path/../${fwdir}/${version}${libnm}"\
753                         "${target}"
754         done
755         if [ ! -d "${condir}/translations" ]; then
756                 mkdir -p "${condir}/translations"
757         fi
758         echo Copy Qt translations to "${condir}/translations"
759         cp -p "${source}"/translations/qt_*.qm "${condir}/translations"
760 }
761
762 # -------------------------
763 # Create universal binaries
764 # -------------------------
765 convert_universal() {
766         cd "${LyxAppPrefix}"
767         for file in ${LYX_FILE_LIST} ; do
768                 OBJ_LIST=
769                 for arch in ${ARCH_LIST} ; do
770                         if [ -f "${BUNDLE_PATH}/${file}-${arch}" ]; then
771                                 OBJ_LIST="${OBJ_LIST} ${BUNDLE_PATH}/${file}-${arch}"
772                         fi
773                 done
774                 if [ -n "${OBJ_LIST}" ]; then
775                         lipo -create ${OBJ_LIST} -o "${BUNDLE_PATH}/${file}"
776                 fi
777                 if [ -f "${LibMagicInstallDir}/lib/${LibMagicLibrary}" -a "yes" = "${libmagic_deployment}" ]; then
778                         private_framework LibMagic "${LibMagicInstallDir}/lib/${LibMagicLibrary}" "${LYX_BUNDLE_PATH}/${file}"
779                 fi
780                 if [ -f "${ASpellInstallDir}/lib/${ASpellLibrary}" -a "yes" = "${aspell_deployment}" ]; then
781                         private_framework Aspell "${ASpellInstallDir}/lib/${ASpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
782                 fi
783                 if [ -f "${HunSpellInstallDir}/lib/${HunSpellLibrary}" -a "yes" = "${hunspell_deployment}" ]; then
784                         private_framework Hunspell "${HunSpellInstallDir}/lib/${HunSpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
785                 fi
786                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
787                         deploy_qtlibs "${LYX_BUNDLE_PATH}/${file}"
788                 fi
789                 otool -L "${BUNDLE_PATH}/${file}" | while read reference ; do
790                         case "${reference}" in
791                         *"${LyxBuildDir}"*"("*")")
792                                 echo ERROR: Bad reference to "${reference}" found!!
793                                 ;;
794                         esac
795                 done
796         done
797         for arch in ${ARCH_LIST} ; do
798                 rm -f ${BUNDLE_PATH}/*-${arch}
799         done
800 }
801
802 deduplicate() {
803         find "$@" -type f -print | while read file ; do
804                 echo $(md5 -q "$file") "$file"
805         done | sort | while read hash file ; do
806                 ppath=$(dirname "$pfile")
807                 path=$(dirname "$file")
808                 if [ "$phash" = "$hash" -a "$ppath" = "$path" ]; then
809                         pname=$(basename "$pfile")
810                         name=$(basename "$file")
811                         cmp -s "$pfile" "$file" && (
812                                 rm "$file"
813                                 cd "$path" && ln -s "$pname" "$name" && echo link for "$file" created
814                         )
815                 fi
816                 phash="$hash"
817                 pfile="$file"
818         done
819 }
820
821 copy_dictionaries() {
822         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_dictionaries}" ]; then
823                 ASpellResources="${LyxAppPrefix}/Contents/Resources"
824                 # try to reuse macports dictionaries for now
825                 if [ -d /opt/local/lib/aspell-0.60 ]; then ASpellInstallDir=/opt/local ; fi
826                 mkdir -p "${ASpellResources}"
827                 echo Copy Aspell dictionaries from "${ASpellInstallDir}"
828                 mkdir -p "${ASpellResources}"/data "${ASpellResources}"/dicts
829                 cp -p -r "${ASpellInstallDir}/lib/aspell-0.60"/* "${ASpellResources}"/data
830                 cp -p -r "${ASpellInstallDir}/share/aspell"/* "${ASpellResources}"/dicts
831         fi
832         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_dictionaries}" ]; then
833                 HunSpellResources="${LyxAppPrefix}/Contents/Resources"
834                 if [ -d "${DictionarySourceDir}" ]; then
835                         ( cd "${DictionarySourceDir}" && find dicts -name .svn -prune -o -type f -print | cpio -pmdv "${HunSpellResources}" )
836                         deduplicate "${HunSpellResources}"/dicts
837                 fi
838         fi
839         if [ -d "${DictionarySourceDir}" -a "yes" = "${thesaurus_deployment}" ]; then
840                 MyThesResources="${LyxAppPrefix}/Contents/Resources"
841                 ( cd "${DictionarySourceDir}" && find thes -name .svn -prune -o -type f -print | cpio -pmdv "${MyThesResources}" )
842                 deduplicate "${MyThesResources}"/thes
843         fi
844 }
845
846 set_bundle_display_options() {
847         X_BOUNDS=$2
848         Y_BOUNDS=$3
849         Y_POSITION=$((Y_BOUNDS - 65))
850         Y_BOUNDS=$((Y_BOUNDS + 20))
851         LYX_X_POSITION=$((X_BOUNDS / 4))
852         LYX_Y_POSITION=$Y_POSITION
853         APP_X_POSITION=$((3 * X_BOUNDS / 4))
854         APP_Y_POSITION=$Y_POSITION
855         WITH_DOCUMENTS=$(test -d "${1}/Documents" && echo true || echo false)
856         osascript <<-EOF
857         tell application "Finder"
858         set f to POSIX file ("${1}" as string) as alias
859         tell folder f
860             open
861             tell container window
862                 set toolbar visible to false
863                 set statusbar visible to false
864                 set current view to icon view
865                 delay 1 -- sync
866                 set the bounds to {20, 50, $X_BOUNDS, $Y_BOUNDS}
867             end tell
868             delay 1 -- sync
869             set icon size of the icon view options of container window to 64
870             set arrangement of the icon view options of container window to not arranged
871             if ${WITH_DOCUMENTS} then
872                set position of item "Documents" to {$LYX_X_POSITION,0}
873             end if
874             set position of item "${LyxName}.app" to {$LYX_X_POSITION,$LYX_Y_POSITION}
875             set position of item "Applications" to {$APP_X_POSITION,$APP_Y_POSITION}
876             set background picture of the icon view options\
877                of container window to file "background.png" of folder "Pictures"
878             set the bounds of the container window to {0, 0, $X_BOUNDS, $Y_BOUNDS}
879             update without registering applications
880             delay 5 -- sync
881             close
882         end tell
883         delay 5 -- sync
884     end tell
885 EOF
886 }
887
888 make_dmg() {
889         cd "${1}"
890
891         BGSIZE=$(file "$DmgBackground" | awk -F , '/PNG/{print $2 }' | tr x ' ')
892         BG_W=$(echo ${BGSIZE} | awk '{print $1 }')
893         BG_H=$(echo ${BGSIZE} | awk '{print $2 }')
894
895         rm -f "${DMGNAME}.sparseimage" "${DMGNAME}.dmg"
896
897         hdiutil create -type SPARSE -size ${DMGSIZE:-"250m"} -fs HFS+ -volname "${LyxBase}" "${DMGNAME}"
898         # Unmount currently mounted disk image
899         mount | grep "${LyxBase}" && umount /Volumes/"${LyxBase}"
900         test -d /Volumes/"${LyxBase}" && rmdir /Volumes/"${LyxBase}"
901
902         # Mount the disk image
903         hdiutil attach "${DMGNAME}.sparseimage"
904
905         # Obtain device information
906         DEVS=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
907         DEV=$(echo $DEVS | cut -f 1 -d ' ')
908         VOLUME=$(mount |grep ${DEV} | cut -f 3 -d ' ')
909
910         # copy in the application bundle
911         cp -Rp "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
912
913         # copy in background image
914         mkdir -p "${VOLUME}/Pictures"
915         cp "${DmgBackground}" "${VOLUME}/Pictures/background.png"
916         # symlink applications
917         ln -s /Applications/ "${VOLUME}"/Applications
918         test -d "${DocumentationDir}" && cp -r "${DocumentationDir}" "${VOLUME}"
919         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
920         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
921         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
922
923         # Unmount the disk image
924         hdiutil detach ${DEV}
925
926         # Convert the disk image to read-only
927         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
928         rm -f "${DMGNAME}.sparseimage"
929 }
930
931 # ------------------------------
932 # Building distribution packages
933 # ------------------------------
934
935 build_package() {
936         test -n "${LyxAppZip}" && (
937                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
938         )
939
940         DMGARCH=""
941         for arch in ${ARCH_LIST} ; do
942                 DMGARCH="${DMGARCH}-${arch}"
943         done
944         QtDmgArchSuffix=${QtMajorVersion}${DMGARCH}${QtAPI}.dmg
945
946         test -n "${DMGLocation}" && (
947                 make_dmg "${DMGLocation}"
948                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
949                         rm -f "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
950                         echo move to "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
951                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
952                 fi
953         )
954 }
955
956 # ------------------------------
957 # main block
958 # ------------------------------
959
960 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
961         build_lyx
962         convert_universal
963         copy_dictionaries
964 fi
965 build_package