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