]> git.lyx.org Git - lyx.git/blob - development/LyX-Mac-binary-release.sh
76bf79b0f2fa83aba93700f40bf0e5b623e98dcd
[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 (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 ${MAKEJOBS} && make install
391         )
392         cd "${QtInstallDir}" && (
393                 mkdir -p include
394                 cd include
395                 for libnm in ${QtLibraries} ; do
396                         test -d ${libnm} -o -L ${libnm} || ln -s ../lib/${libnm}.framework/Headers ${libnm}
397                 done
398         )
399 fi
400
401 if [ -d "${LibMagicSourceDir}" -a ! -f "${LibMagicInstallHdr}" ]; then
402         # we have a private libmagic (file(1)) source tree at hand...
403         # so let's build and install it
404         if [ -z "${LibMagicVersion}" ]; then
405                 LibMagicVersion=$(grep AC_INIT "${LibMagicSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
406         fi
407
408         LibMagicName="LibMagic"
409         LibMagicBase="${LibMagicName}-${LibMagicVersion}"
410
411         echo Build libmagic library ${LibMagicBase}
412         echo configure options:
413         echo --prefix="${LibMagicInstallDir}" ${LibMagicConfigureOptions}
414
415         mkdir -p "${LibMagicBuildDir}" && cd "${LibMagicBuildDir}"
416
417         # ----------------------------------------
418         # Build LibMagic for different architectures
419         # ----------------------------------------
420         FILE_LIST="${LibMagicLibrary}"
421
422         for arch in ${ARCH_LIST} ; do
423                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
424                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
425                 "${LibMagicSourceDir}/configure"\
426                         --prefix="${LibMagicInstallDir}"\
427                         ${LibMagicConfigureOptions}
428                 make && make install${strip}
429                 for file in ${FILE_LIST} ; do
430                         if [ -f "${LibMagicInstallDir}"/lib/${file} ]; then
431                                 mv "${LibMagicInstallDir}"/lib/${file}\
432                                         "${LibMagicInstallDir}"/lib/${file}-${arch} 
433                         else
434                                 echo Cannot build and install LibMagic for ${arch}.
435                                 exit 1
436                         fi
437                 done
438         done
439         # -------------------------
440         # Create universal binaries
441         # -------------------------
442         for file in ${FILE_LIST} ; do
443                 OBJ_LIST=
444                 for arch in ${ARCH_LIST} ; do
445                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
446                 done
447                 (
448                         cd "${LibMagicInstallDir}"
449                         lipo -create ${OBJ_LIST} -o lib/${file}
450                         # check for the "missing link"...
451                         test -f lib/libmagic.dylib || (cd lib ; ln -s "${LibMagicLibrary}" libmagic.dylib)
452                 )
453         done
454         # --------
455         # Clean up
456         # --------
457         for arch in ${ARCH_LIST} ; do
458                 rm -f "${LibMagicInstallDir}"/lib/*-${arch}
459         done
460 fi
461
462 if [ -d "${HunSpellSourceDir}" -a ! -f "${HunSpellInstallHdr}" ]; then
463         # we have a private HunSpell source tree at hand...
464         # so let's build and install it
465         if [ -z "${HunSpellVersion}" ]; then
466                 HunSpellVersion=$(grep AC_INIT "${HunSpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
467         fi
468
469         HunSpellName="Hunspell"
470         HunSpellBase="${HunSpellName}-${HunSpellVersion}"
471
472         echo Build hunspell library ${HunSpellBase}
473         echo configure options:
474         echo --prefix="${HunSpellInstallDir}" ${HunspellConfigureOptions}
475
476         mkdir -p "${HunSpellBuildDir}" && cd "${HunSpellBuildDir}"
477
478         # ----------------------------------------
479         # Build HunSpell for different architectures
480         # ----------------------------------------
481         FILE_LIST="${HunSpellLibrary}"
482
483         for arch in ${ARCH_LIST} ; do
484                 make distclean
485                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
486                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
487                 "${HunSpellSourceDir}/configure"\
488                         --prefix="${HunSpellInstallDir}"\
489                         ${HunspellConfigureOptions}
490                 make && make install${strip}
491                 for file in ${FILE_LIST} ; do
492                         if [ -f "${HunSpellInstallDir}"/lib/${file} ]; then
493                                 mv "${HunSpellInstallDir}"/lib/${file}\
494                                         "${HunSpellInstallDir}"/lib/${file}-${arch} 
495                         else
496                                 echo Cannot build and install HunSpell for ${arch}.
497                                 exit 1
498                         fi
499                 done
500         done
501         # -------------------------
502         # Create universal binaries
503         # -------------------------
504         for file in ${FILE_LIST} ; do
505                 OBJ_LIST=
506                 for arch in ${ARCH_LIST} ; do
507                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
508                 done
509                 (
510                         cd "${HunSpellInstallDir}"
511                         lipo -create ${OBJ_LIST} -o lib/${file}
512                         # check for the "missing link"...
513                         test -f lib/libhunspell.dylib || (cd lib ; ln -s "${HunSpellLibrary}" libhunspell.dylib)
514                 )
515         done
516         # --------
517         # Clean up
518         # --------
519         for arch in ${ARCH_LIST} ; do
520                 rm -f "${HunSpellInstallDir}"/lib/*-${arch}
521         done
522 fi
523
524 if [ -d "${ASpellSourceDir}" -a ! -f "${ASpellInstallHdr}" -a "yes" = "${aspell_deployment}" ]; then
525         # we have a private ASpell source tree at hand...
526         # so let's build and install it
527         if [ -z "${ASpellVersion}" ]; then
528                 ASpellVersion=$(grep AC_INIT "${ASpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
529         fi
530
531         ASpellName="Aspell"
532         ASpellBase="${ASpellName}-${ASpellVersion}"
533
534         echo Build aspell library ${ASpellBase}
535         echo configure options:
536         echo --prefix="${ASpellInstallDir}" ${AspellConfigureOptions}
537
538         # ASpell builds inplace only :(
539         cd "${ASpellSourceDir}"
540
541         # ----------------------------------------
542         # Build ASpell for different architectures
543         # ----------------------------------------
544         FILE_LIST="${ASpellLibrary}"
545
546         for arch in ${ARCH_LIST} ; do
547                 make distclean
548                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
549                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
550                 CXXFLAGS=-g "${ASpellSourceDir}/configure"\
551                         --prefix="${ASpellInstallDir}"\
552                         ${AspellConfigureOptions}
553                 make && make install${aspellstrip}
554                 for file in ${FILE_LIST} ; do
555                         if [ -f "${ASpellInstallDir}"/lib/${file} ]; then
556                                 mv "${ASpellInstallDir}"/lib/${file}\
557                                         "${ASpellInstallDir}"/lib/${file}-${arch} 
558                         else
559                                 echo Cannot build and install ASpell for ${arch}.
560                                 exit 1
561                         fi
562                 done
563         done
564         # -------------------------
565         # Create universal binaries
566         # -------------------------
567         for file in ${FILE_LIST} ; do
568                 OBJ_LIST=
569                 for arch in ${ARCH_LIST} ; do
570                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
571                 done
572                 (
573                         cd "${ASpellInstallDir}"
574                         lipo -create ${OBJ_LIST} -o lib/${file}
575                 )
576         done
577         # --------
578         # Clean up
579         # --------
580         for arch in ${ARCH_LIST} ; do
581                 rm -f "${ASpellInstallDir}"/lib/*-${arch}
582         done
583 fi
584
585
586 framework_name() {
587         echo "Frameworks/${1}.framework"
588 }
589
590 LYX_FILE_LIST="lyx lyxclient tex2lyx"
591 BUNDLE_PATH="Contents/MacOS"
592 LYX_BUNDLE_PATH="${LyxAppPrefix}/${BUNDLE_PATH}"
593 build_lyx() {
594         # Clear Output
595         if [ -n "${LyxAppZip}" -a -f "${LyxAppZip}" ]; then rm "${LyxAppZip}"; fi
596         if [ -d "${LyxAppPrefix}" ]; then rm -rf "${LyxAppPrefix}"; fi
597
598         # -------------------------------------
599         # Automate configure check
600         # -------------------------------------
601         if [ ! -f "${LyxSourceDir}"/configure -o "${LyxSourceDir}"/configure -ot "${LyxSourceDir}"/configure.ac ]; then
602                 ( cd "${LyxSourceDir}" && sh autogen.sh )
603         else
604                 find "${LyxSourceDir}" -name Makefile.am -print | while read file ; do
605                         dname=$(dirname "$file")
606                         if [ -f "$dname/Makefile.in" -a "$dname/Makefile.in" -ot "$file" ]; then
607                                 ( cd "${LyxSourceDir}" && sh autogen.sh )
608                                 break
609                         fi
610                 done
611         fi
612         # -------------------------------------
613         # Build LyX for different architectures
614         # -------------------------------------
615
616         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_deployment}" ]; then
617                 ConfigureExtraInc="--with-extra-inc=${ASpellInstallDir}/include"
618                 ConfigureExtraLib="--with-extra-lib=${ASpellInstallDir}/lib"
619         fi
620
621         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_deployment}" ]; then
622                 HunSpellFramework=$(framework_name Hunspell)
623                 HunSpellFramework=$(basename "${HunSpellFramework}")
624                 ConfigureExtraInc="--with-extra-inc=${HunSpellInstallDir}/include"
625                 ConfigureExtraLib="--with-extra-lib=${HunSpellInstallDir}/lib"
626                 # LyXConfigureOptions="${LyXConfigureOptions} --with-hunspell-framework=${HunSpellFramework}"
627         fi
628         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraInc}"
629         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraLib}"
630
631         for arch in ${ARCH_LIST} ; do
632
633                 if [ -d "${LyxBuildDir}" ];  then rm -r "${LyxBuildDir}"; fi
634                 mkdir -p "${LyxBuildDir}" && cd "${LyxBuildDir}"
635
636                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
637                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
638
639                 if [ "$configure_qt_frameworks" = "yes" ]; then
640                         export QT_CORE_CFLAGS="-FQtCore"
641                         export QT_CORE_LIBS="-framework QtCore"
642                         export QT_FRONTEND_CFLAGS="-FQtGui"
643                         export QT_FRONTEND_LIBS="-framework QtGui"
644                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtCore.framework/Headers"
645                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtGui.framework/Headers"
646                 fi
647
648                 echo LDFLAGS="${LDFLAGS}"
649                 export LDFLAGS
650                 echo CPPFLAGS="${CPPFLAGS}"
651                 export CPPFLAGS
652                 echo CONFIGURE_OPTIONS="${LyXConfigureOptions}" ${QtInstallDir:+"--with-qt-dir=${QtInstallDir}"}
653                 "${LyxSourceDir}/configure"\
654                         --prefix="${LyxAppPrefix}" --with-version-suffix="-${LyXVersionSuffix}"\
655                         ${QtInstallDir:+"--with-qt-dir=${QtInstallDir}"} \
656                         ${LyXConfigureOptions}\
657                         --enable-build-type=rel && \
658                 make ${MAKEJOBS} && make install${strip}
659                 for file in ${LYX_FILE_LIST} ; do
660                         if [ -f "${LYX_BUNDLE_PATH}/${file}" ]; then
661                                 mv "${LYX_BUNDLE_PATH}/${file}"\
662                                         "${LYX_BUNDLE_PATH}/${file}-${arch}" 
663                         else
664                                 echo ERROR: Cannot build and install LyX for ${arch}.
665                                 exit 1
666                         fi
667                 done
668         done
669 }
670
671 content_directory() {
672         target="$1"
673         content=$(dirname "${target}")
674         content=$(dirname "${content}")
675         echo "${content}"
676 }
677
678 private_framework() {
679         fwdir=$(framework_name "$1")
680         source="$2"
681         target="$3"
682         condir=$(content_directory "${target}")
683         libnm=$(basename "${source}")
684         mkdir -p "${condir}/${fwdir}"
685         if [ ! -f "${condir}/${fwdir}/${libnm}" ]; then
686                 cp -p "${source}" "${condir}/${fwdir}"
687                 echo Set library id in "${condir}/${fwdir}/${libnm}"
688                 install_name_tool -id "@executable_path/../${fwdir}/${libnm}" "${condir}/${fwdir}/${libnm}"
689         fi
690         echo Correct library id reference to "${libnm}" in "${target}"
691         install_name_tool -change "${source}" "@executable_path/../${fwdir}/${libnm}" "${target}"
692 }
693
694 deploy_qtlibs() {
695         source="${QtInstallDir}"
696         target="$1"
697         version="Versions/${QtFrameworkVersion}/"
698         condir=$(content_directory "${target}")
699         mkdir -p "${condir}/Resources"
700         test -f "${condir}/Resources/qt.conf" || cat - > "${condir}/Resources/qt.conf" <<-EOF
701 [Paths]
702 Plugins = PlugIns
703 Translations = translations
704 EOF
705         if [ ! -d "${condir}/PlugIns" ]; then
706                 mkdir -p "${condir}/PlugIns"
707                 find "${source}/plugins" -name \*.dylib -print | grep -v _debug.dylib | while read libname ; do
708                         echo Copy plugin "${libname}"
709                         dylib=$(basename "${libname}")
710                         dirname=$(dirname "${libname}")
711                         dirname=$(basename "${dirname}")
712                         mkdir -p "${condir}/PlugIns/${dirname}"
713                         cp -p "${libname}" "${condir}/PlugIns/${dirname}"
714                 done
715         fi
716         for libnm in ${QtLibraries} ; do
717                 fwdir=$(framework_name "$libnm")
718                 dirname=$(dirname "${fwdir}")
719                 mkdir -p "${condir}/${dirname}"
720                 dirname=$(basename "${fwdir}")
721                 test -d "${condir}/${fwdir}" || (
722                         echo Copy framework "${source}/lib/"$(basename "${fwdir}")
723                         cp -pR "${source}/lib/"$(basename "${fwdir}") "${condir}/${fwdir}"
724                         echo Set library id in "${condir}/${fwdir}/${version}${libnm}"
725                         install_name_tool -id "@executable_path/../${fwdir}/${version}${libnm}" "${condir}/${fwdir}/${version}${libnm}"
726                         find "${condir}/PlugIns" "${condir}/"$(dirname "${fwdir}") -name Headers -prune -o -type f -print | while read filename ; do
727                                 if [ "${filename}" != "${target}" ]; then
728                                         otool -L "${filename}" 2>/dev/null | sort -u | while read library ; do
729                                                 # pattern match for: /path/to/qt/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.6.0, current version 4.6.2)
730                                                 case "${library}" in
731                                                 *"${libnm}"*"("*version*")"*)
732                                                         echo Correct library id reference to "${libnm}" in "${filename}"
733                                                         install_name_tool -change\
734                                                                 "${source}/lib/${dirname}/${version}${libnm}"\
735                                                                 "@executable_path/../${fwdir}/${version}${libnm}"\
736                                                                 "${filename}"
737                                                         ;;
738                                                 esac
739                                         done
740                                 fi
741                         done
742                 )
743                 echo Correct library id reference to "${libnm}" in "${target}"
744                 install_name_tool -change\
745                         "${source}/lib/${dirname}/${version}${libnm}"\
746                         "@executable_path/../${fwdir}/${version}${libnm}"\
747                         "${target}"
748         done
749         if [ ! -d "${condir}/translations" ]; then
750                 mkdir -p "${condir}/translations"
751         fi
752         echo Copy Qt translations to "${condir}/translations"
753         cp -p "${source}"/translations/qt_*.qm "${condir}/translations"
754 }
755
756 # -------------------------
757 # Create universal binaries
758 # -------------------------
759 convert_universal() {
760         cd "${LyxAppPrefix}"
761         for file in ${LYX_FILE_LIST} ; do
762                 OBJ_LIST=
763                 for arch in ${ARCH_LIST} ; do
764                         if [ -f "${BUNDLE_PATH}/${file}-${arch}" ]; then
765                                 OBJ_LIST="${OBJ_LIST} ${BUNDLE_PATH}/${file}-${arch}"
766                         fi
767                 done
768                 if [ -n "${OBJ_LIST}" ]; then
769                         lipo -create ${OBJ_LIST} -o "${BUNDLE_PATH}/${file}"
770                 fi
771                 if [ -f "${LibMagicInstallDir}/lib/${LibMagicLibrary}" -a "yes" = "${libmagic_deployment}" ]; then
772                         private_framework LibMagic "${LibMagicInstallDir}/lib/${LibMagicLibrary}" "${LYX_BUNDLE_PATH}/${file}"
773                 fi
774                 if [ -f "${ASpellInstallDir}/lib/${ASpellLibrary}" -a "yes" = "${aspell_deployment}" ]; then
775                         private_framework Aspell "${ASpellInstallDir}/lib/${ASpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
776                 fi
777                 if [ -f "${HunSpellInstallDir}/lib/${HunSpellLibrary}" -a "yes" = "${hunspell_deployment}" ]; then
778                         private_framework Hunspell "${HunSpellInstallDir}/lib/${HunSpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
779                 fi
780                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
781                         deploy_qtlibs "${LYX_BUNDLE_PATH}/${file}"
782                 fi
783                 otool -L "${BUNDLE_PATH}/${file}" | while read reference ; do
784                         case "${reference}" in
785                         *"${LyxBuildDir}"*"("*")")
786                                 echo ERROR: Bad reference to "${reference}" found!!
787                                 ;;
788                         esac
789                 done
790         done
791         for arch in ${ARCH_LIST} ; do
792                 rm -f ${BUNDLE_PATH}/*-${arch}
793         done
794 }
795
796 copy_dictionaries() {
797         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_dictionaries}" ]; then
798                 ASpellResources="${LyxAppPrefix}/Contents/Resources"
799                 # try to reuse macports dictionaries for now
800                 if [ -d /opt/local/lib/aspell-0.60 ]; then ASpellInstallDir=/opt/local ; fi
801                 mkdir -p "${ASpellResources}"
802                 echo Copy Aspell dictionaries from "${ASpellInstallDir}"
803                 mkdir -p "${ASpellResources}"/data "${ASpellResources}"/dicts
804                 cp -p -r "${ASpellInstallDir}/lib/aspell-0.60"/* "${ASpellResources}"/data
805                 cp -p -r "${ASpellInstallDir}/share/aspell"/* "${ASpellResources}"/dicts
806         fi
807         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_dictionaries}" ]; then
808                 HunSpellResources="${LyxAppPrefix}/Contents/Resources"
809                 if [ -d "${DictionarySourceDir}" ]; then
810                         ( cd "${DictionarySourceDir}" && find dicts -name .svn -prune -o -type f -print | cpio -pmdv "${HunSpellResources}" )
811                 fi
812         fi
813         if [ -d "${DictionarySourceDir}" -a "yes" = "${thesaurus_deployment}" ]; then
814                 MyThesResources="${LyxAppPrefix}/Contents/Resources"
815                 ( cd "${DictionarySourceDir}" && find thes -name .svn -prune -o -type f -print | cpio -pmdv "${MyThesResources}" )
816         fi
817 }
818
819 set_bundle_display_options() {
820         X_BOUNDS=$2
821         Y_BOUNDS=$3
822         Y_POSITION=$((Y_BOUNDS - 65))
823         Y_BOUNDS=$((Y_BOUNDS + 20))
824         LYX_X_POSITION=$((X_BOUNDS / 4))
825         LYX_Y_POSITION=$Y_POSITION
826         APP_X_POSITION=$((3 * X_BOUNDS / 4))
827         APP_Y_POSITION=$Y_POSITION
828         WITH_DOCUMENTS=$(test -d "${1}/Documents" && echo true || echo false)
829         osascript <<-EOF
830         tell application "Finder"
831         set f to POSIX file ("${1}" as string) as alias
832         tell folder f
833             open
834             tell container window
835                 set toolbar visible to false
836                 set statusbar visible to false
837                 set current view to icon view
838                 delay 1 -- sync
839                 set the bounds to {20, 50, $X_BOUNDS, $Y_BOUNDS}
840             end tell
841             delay 1 -- sync
842             set icon size of the icon view options of container window to 64
843             set arrangement of the icon view options of container window to not arranged
844             if ${WITH_DOCUMENTS} then
845                set position of item "Documents" to {$LYX_X_POSITION,0}
846             end if
847             set position of item "${LyxName}.app" to {$LYX_X_POSITION,$LYX_Y_POSITION}
848             set position of item "Applications" to {$APP_X_POSITION,$APP_Y_POSITION}
849             set background picture of the icon view options\
850                of container window to file "background.png" of folder "Pictures"
851             set the bounds of the container window to {0, 0, $X_BOUNDS, $Y_BOUNDS}
852             update without registering applications
853             delay 5 -- sync
854             close
855         end tell
856         delay 5 -- sync
857     end tell
858 EOF
859 }
860
861 make_dmg() {
862         cd "${1}"
863
864         BGSIZE=$(file "$DmgBackground" | awk -F , '/PNG/{print $2 }' | tr x ' ')
865         BG_W=$(echo ${BGSIZE} | awk '{print $1 }')
866         BG_H=$(echo ${BGSIZE} | awk '{print $2 }')
867
868         rm -f "${DMGNAME}.sparseimage" "${DMGNAME}.dmg"
869
870         hdiutil create -type SPARSE -size ${DMGSIZE:-"250m"} -fs HFS+ -volname "${LyxBase}" "${DMGNAME}"
871         # Unmount currently mounted disk image
872         mount | grep "${LyxBase}" && umount /Volumes/"${LyxBase}"
873         test -d /Volumes/"${LyxBase}" && rmdir /Volumes/"${LyxBase}"
874
875         # Mount the disk image
876         hdiutil attach "${DMGNAME}.sparseimage"
877
878         # Obtain device information
879         DEVS=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
880         DEV=$(echo $DEVS | cut -f 1 -d ' ')
881         VOLUME=$(mount |grep ${DEV} | cut -f 3 -d ' ')
882
883         # copy in the application bundle
884         cp -Rp "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
885
886         # copy in background image
887         mkdir -p "${VOLUME}/Pictures"
888         cp "${DmgBackground}" "${VOLUME}/Pictures/background.png"
889         # symlink applications
890         ln -s /Applications/ "${VOLUME}"/Applications
891         test -d "${DocumentationDir}" && cp -r "${DocumentationDir}" "${VOLUME}"
892         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
893         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
894         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
895
896         # Unmount the disk image
897         hdiutil detach ${DEV}
898
899         # Convert the disk image to read-only
900         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
901         rm -f "${DMGNAME}.sparseimage"
902 }
903
904 # ------------------------------
905 # Building distribution packages
906 # ------------------------------
907
908 build_package() {
909         test -n "${LyxAppZip}" && (
910                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
911         )
912
913         DMGARCH=""
914         for arch in ${ARCH_LIST} ; do
915                 DMGARCH="${DMGARCH}-${arch}"
916         done
917         QtDmgArchSuffix=${QtMajorVersion}${DMGARCH}${QtAPI}.dmg
918
919         test -n "${DMGLocation}" && (
920                 make_dmg "${DMGLocation}"
921                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
922                         rm -f "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
923                         echo move to "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
924                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
925                 fi
926         )
927 }
928
929 # ------------------------------
930 # main block
931 # ------------------------------
932
933 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
934         build_lyx
935         convert_universal
936         copy_dictionaries
937 fi
938 build_package