]> git.lyx.org Git - lyx.git/blob - development/LyX-Mac-binary-release.sh
45adfd8f286adfeee9eb2f41e86099ffd979c7fb
[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)
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*)
332         QtLibraries="QtSvg QtXml QtPrintSupport QtMacExtras QtWidgets QtGui QtNetwork QtConcurrent QtCore"
333         QtFrameworkVersion="5"
334         ;;
335 *)
336         QtLibraries="QtSvg QtXml QtGui QtNetwork QtCore"
337         QtFrameworkVersion="4"
338         ;;
339 esac
340
341 DMGNAME="${LyxBase}"
342 DMGSIZE="550m"
343
344 # Check for existing SDKs
345 SDKs=$(echo ${DEVELOPER_SDKS}/MacOSX10*sdk)
346 case $SDKs in
347 *${SDKROOT}*)
348         ;;
349 *10.6*)
350         MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"10.5"}; export MACOSX_DEPLOYMENT_TARGET
351         case "${MACOSX_DEPLOYMENT_TARGET}" in
352         10.6)
353                 SDKROOT="${DEVELOPER_SDKS}/MacOSX10.6.sdk"; export SDKROOT
354                 ;;
355         10.5|10.4)
356                 SDKROOT=${SDKROOT:-"${DEVELOPER_SDKS}/MacOSX10.5.sdk"}; export SDKROOT
357                 ;;
358         esac
359         ;;
360 *10.5*)
361         MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-"10.4"}; export MACOSX_DEPLOYMENT_TARGET
362         SDKROOT=${SDKROOT:-"${DEVELOPER_SDKS}/MacOSX10.5.sdk"}; export SDKROOT
363         ;;
364 *)
365         echo Unknown or missing SDK for Mac OS X.
366         exit 1
367         ;;
368 esac
369 MYCFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
370
371 if [ "${configure_qt_frameworks}" != "yes" -a -d "${QtSourceDir}" -a ! \( -d "${QtBuildDir}" -a -d "${QtInstallDir}" \) ]; then
372         echo Build Qt library ${QtSourceDir}
373         if [ "${QtInstallDir}" = "${QtBuildDir}" ]; then
374                 echo Bad install directory for Qt.
375                 echo Must be different from build directory "${QtBuildDir}".
376                 exit 1
377         fi
378         (
379                 mkdir -p "${QtBuildDir}" && cd "${QtBuildDir}"
380                 for arch in ${ARCH_LIST} ; do
381                         ARCHS="${ARCHS} -arch ${arch}"
382                 done
383                 echo configure options:
384                 echo ${QtConfigureOptions} ${ARCHS} -prefix "${QtInstallDir}"
385                 "${QtSourceDir}"/configure ${QtConfigureOptions} ${ARCHS} -prefix "${QtInstallDir}"
386                 make ${MAKEJOBS} && make install
387         )
388         cd "${QtInstallDir}" && (
389                 mkdir -p include
390                 cd include
391                 for libnm in ${QtLibraries} ; do
392                         test -d ${libnm} -o -L ${libnm} || ln -s ../lib/${libnm}.framework/Headers ${libnm}
393                 done
394         )
395 fi
396
397 if [ -d "${LibMagicSourceDir}" -a ! -f "${LibMagicInstallHdr}" ]; then
398         # we have a private libmagic (file(1)) source tree at hand...
399         # so let's build and install it
400         if [ -z "${LibMagicVersion}" ]; then
401                 LibMagicVersion=$(grep AC_INIT "${LibMagicSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
402         fi
403
404         LibMagicName="LibMagic"
405         LibMagicBase="${LibMagicName}-${LibMagicVersion}"
406
407         echo Build libmagic library ${LibMagicBase}
408         echo configure options:
409         echo --prefix="${LibMagicInstallDir}" ${LibMagicConfigureOptions}
410
411         mkdir -p "${LibMagicBuildDir}" && cd "${LibMagicBuildDir}"
412
413         # ----------------------------------------
414         # Build LibMagic for different architectures
415         # ----------------------------------------
416         FILE_LIST="${LibMagicLibrary}"
417
418         for arch in ${ARCH_LIST} ; do
419                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
420                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
421                 "${LibMagicSourceDir}/configure"\
422                         --prefix="${LibMagicInstallDir}"\
423                         ${LibMagicConfigureOptions}
424                 make && make install${strip}
425                 for file in ${FILE_LIST} ; do
426                         if [ -f "${LibMagicInstallDir}"/lib/${file} ]; then
427                                 mv "${LibMagicInstallDir}"/lib/${file}\
428                                         "${LibMagicInstallDir}"/lib/${file}-${arch} 
429                         else
430                                 echo Cannot build and install LibMagic for ${arch}.
431                                 exit 1
432                         fi
433                 done
434         done
435         # -------------------------
436         # Create universal binaries
437         # -------------------------
438         for file in ${FILE_LIST} ; do
439                 OBJ_LIST=
440                 for arch in ${ARCH_LIST} ; do
441                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
442                 done
443                 (
444                         cd "${LibMagicInstallDir}"
445                         lipo -create ${OBJ_LIST} -o lib/${file}
446                         # check for the "missing link"...
447                         test -f lib/libmagic.dylib || (cd lib ; ln -s "${LibMagicLibrary}" libmagic.dylib)
448                 )
449         done
450         # --------
451         # Clean up
452         # --------
453         for arch in ${ARCH_LIST} ; do
454                 rm -f "${LibMagicInstallDir}"/lib/*-${arch}
455         done
456 fi
457
458 if [ -d "${HunSpellSourceDir}" -a ! -f "${HunSpellInstallHdr}" ]; then
459         # we have a private HunSpell source tree at hand...
460         # so let's build and install it
461         if [ -z "${HunSpellVersion}" ]; then
462                 HunSpellVersion=$(grep AC_INIT "${HunSpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
463         fi
464
465         HunSpellName="Hunspell"
466         HunSpellBase="${HunSpellName}-${HunSpellVersion}"
467
468         echo Build hunspell library ${HunSpellBase}
469         echo configure options:
470         echo --prefix="${HunSpellInstallDir}" ${HunspellConfigureOptions}
471
472         mkdir -p "${HunSpellBuildDir}" && cd "${HunSpellBuildDir}"
473
474         # ----------------------------------------
475         # Build HunSpell for different architectures
476         # ----------------------------------------
477         FILE_LIST="${HunSpellLibrary}"
478
479         for arch in ${ARCH_LIST} ; do
480                 make distclean
481                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
482                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
483                 "${HunSpellSourceDir}/configure"\
484                         --prefix="${HunSpellInstallDir}"\
485                         ${HunspellConfigureOptions}
486                 make && make install${strip}
487                 for file in ${FILE_LIST} ; do
488                         if [ -f "${HunSpellInstallDir}"/lib/${file} ]; then
489                                 mv "${HunSpellInstallDir}"/lib/${file}\
490                                         "${HunSpellInstallDir}"/lib/${file}-${arch} 
491                         else
492                                 echo Cannot build and install HunSpell for ${arch}.
493                                 exit 1
494                         fi
495                 done
496         done
497         # -------------------------
498         # Create universal binaries
499         # -------------------------
500         for file in ${FILE_LIST} ; do
501                 OBJ_LIST=
502                 for arch in ${ARCH_LIST} ; do
503                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
504                 done
505                 (
506                         cd "${HunSpellInstallDir}"
507                         lipo -create ${OBJ_LIST} -o lib/${file}
508                         # check for the "missing link"...
509                         test -f lib/libhunspell.dylib || (cd lib ; ln -s "${HunSpellLibrary}" libhunspell.dylib)
510                 )
511         done
512         # --------
513         # Clean up
514         # --------
515         for arch in ${ARCH_LIST} ; do
516                 rm -f "${HunSpellInstallDir}"/lib/*-${arch}
517         done
518 fi
519
520 if [ -d "${ASpellSourceDir}" -a ! -f "${ASpellInstallHdr}" -a "yes" = "${aspell_deployment}" ]; then
521         # we have a private ASpell source tree at hand...
522         # so let's build and install it
523         if [ -z "${ASpellVersion}" ]; then
524                 ASpellVersion=$(grep AC_INIT "${ASpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
525         fi
526
527         ASpellName="Aspell"
528         ASpellBase="${ASpellName}-${ASpellVersion}"
529
530         echo Build aspell library ${ASpellBase}
531         echo configure options:
532         echo --prefix="${ASpellInstallDir}" ${AspellConfigureOptions}
533
534         # ASpell builds inplace only :(
535         cd "${ASpellSourceDir}"
536
537         # ----------------------------------------
538         # Build ASpell for different architectures
539         # ----------------------------------------
540         FILE_LIST="${ASpellLibrary}"
541
542         for arch in ${ARCH_LIST} ; do
543                 make distclean
544                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
545                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
546                 CXXFLAGS=-g "${ASpellSourceDir}/configure"\
547                         --prefix="${ASpellInstallDir}"\
548                         ${AspellConfigureOptions}
549                 make && make install${aspellstrip}
550                 for file in ${FILE_LIST} ; do
551                         if [ -f "${ASpellInstallDir}"/lib/${file} ]; then
552                                 mv "${ASpellInstallDir}"/lib/${file}\
553                                         "${ASpellInstallDir}"/lib/${file}-${arch} 
554                         else
555                                 echo Cannot build and install ASpell for ${arch}.
556                                 exit 1
557                         fi
558                 done
559         done
560         # -------------------------
561         # Create universal binaries
562         # -------------------------
563         for file in ${FILE_LIST} ; do
564                 OBJ_LIST=
565                 for arch in ${ARCH_LIST} ; do
566                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
567                 done
568                 (
569                         cd "${ASpellInstallDir}"
570                         lipo -create ${OBJ_LIST} -o lib/${file}
571                 )
572         done
573         # --------
574         # Clean up
575         # --------
576         for arch in ${ARCH_LIST} ; do
577                 rm -f "${ASpellInstallDir}"/lib/*-${arch}
578         done
579 fi
580
581
582 framework_name() {
583         echo "Frameworks/${1}.framework"
584 }
585
586 LYX_FILE_LIST="lyx lyxclient tex2lyx"
587 BUNDLE_PATH="Contents/MacOS"
588 LYX_BUNDLE_PATH="${LyxAppPrefix}/${BUNDLE_PATH}"
589 build_lyx() {
590         # Clear Output
591         if [ -n "${LyxAppZip}" -a -f "${LyxAppZip}" ]; then rm "${LyxAppZip}"; fi
592         if [ -d "${LyxAppPrefix}" ]; then rm -rf "${LyxAppPrefix}"; fi
593
594         # -------------------------------------
595         # Automate configure check
596         # -------------------------------------
597         if [ ! -f "${LyxSourceDir}"/configure -o "${LyxSourceDir}"/configure -ot "${LyxSourceDir}"/configure.ac ]; then
598                 ( cd "${LyxSourceDir}" && sh autogen.sh )
599         else
600                 find "${LyxSourceDir}" -name Makefile.am -print | while read file ; do
601                         dname=$(dirname "$file")
602                         if [ -f "$dname/Makefile.in" -a "$dname/Makefile.in" -ot "$file" ]; then
603                                 ( cd "${LyxSourceDir}" && sh autogen.sh )
604                                 break
605                         fi
606                 done
607         fi
608         # -------------------------------------
609         # Build LyX for different architectures
610         # -------------------------------------
611
612         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_deployment}" ]; then
613                 ConfigureExtraInc="--with-extra-inc=${ASpellInstallDir}/include"
614                 ConfigureExtraLib="--with-extra-lib=${ASpellInstallDir}/lib"
615         fi
616
617         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_deployment}" ]; then
618                 HunSpellFramework=$(framework_name Hunspell)
619                 HunSpellFramework=$(basename "${HunSpellFramework}")
620                 ConfigureExtraInc="--with-extra-inc=${HunSpellInstallDir}/include"
621                 ConfigureExtraLib="--with-extra-lib=${HunSpellInstallDir}/lib"
622                 # LyXConfigureOptions="${LyXConfigureOptions} --with-hunspell-framework=${HunSpellFramework}"
623         fi
624         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraInc}"
625         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraLib}"
626
627         for arch in ${ARCH_LIST} ; do
628
629                 if [ -d "${LyxBuildDir}" ];  then rm -r "${LyxBuildDir}"; fi
630                 mkdir -p "${LyxBuildDir}" && cd "${LyxBuildDir}"
631
632                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
633                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
634
635                 if [ -n "${LyXGitCommitHash}" ]; then
636                         CPPFLAGS="${CPPFLAGS} -DLYX_GIT_COMMIT_HASH='${LyXGitCommitHash}'"
637                 fi
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         test -d /Volumes/"${LyxBase}" && umount /Volumes/"${LyxBase}"
873
874         # Mount the disk image
875         hdiutil attach "${DMGNAME}.sparseimage"
876
877         # Obtain device information
878         DEVS=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
879         DEV=$(echo $DEVS | cut -f 1 -d ' ')
880         VOLUME=$(mount |grep ${DEV} | cut -f 3 -d ' ')
881
882         # copy in the application bundle
883         cp -Rp "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
884
885         # copy in background image
886         mkdir -p "${VOLUME}/Pictures"
887         cp "${DmgBackground}" "${VOLUME}/Pictures/background.png"
888         # symlink applications
889         ln -s /Applications/ "${VOLUME}"/Applications
890         test -d "${DocumentationDir}" && cp -r "${DocumentationDir}" "${VOLUME}"
891         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
892         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
893         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
894
895         # Unmount the disk image
896         hdiutil detach ${DEV}
897
898         # Convert the disk image to read-only
899         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
900         rm -f "${DMGNAME}.sparseimage"
901 }
902
903 # ------------------------------
904 # Building distribution packages
905 # ------------------------------
906
907 build_package() {
908         test -n "${LyxAppZip}" && (
909                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
910         )
911
912         DMGARCH=""
913         for arch in ${ARCH_LIST} ; do
914                 DMGARCH="${DMGARCH}-${arch}"
915         done
916         QtDmgArchSuffix=${QtMajorVersion}${DMGARCH}${QtAPI}.dmg
917
918         test -n "${DMGLocation}" && (
919                 make_dmg "${DMGLocation}"
920                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
921                         rm -f "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
922                         echo move to "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
923                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
924                 fi
925         )
926 }
927
928 # ------------------------------
929 # main block
930 # ------------------------------
931
932 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
933         build_lyx
934         convert_universal
935         copy_dictionaries
936 fi
937 build_package