]> git.lyx.org Git - lyx.git/blob - development/LyX-Mac-binary-release.sh
Correctly set language after intitle paragraphs
[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.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 (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*|5.7*)
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                 shift
191                 ;;
192         --with-macosx-target=*)
193                 MACOSX_DEPLOYMENT_TARGET=$(echo ${1}|cut -d= -f2)
194                 shift
195                 ;;
196         --with-sdkroot=*)
197                 SDKROOT=$(echo ${1}|cut -d= -f2)
198                 case "${SDKROOT}" in
199                 10.4)
200                         SDKROOT="${DEVELOPER_SDKS}/MacOSX10.4u.sdk"
201                         export CC=gcc-4.0
202                         export OBJC=gcc-4.0
203                         export CXX=g++-4.0
204                         ;;
205                 *)
206                         SDKROOT="${DEVELOPER_SDKS}/MacOSX${SDKROOT}.sdk"
207                         if [ ! -d "${SDKROOT}" ]; then
208                                 echo Invalid SDKROOT given: "${SDKROOT}"
209                                 usage --help=short
210                         fi
211                         ;;
212                 esac
213                 shift
214                 ;;
215         --libmagic-deployment=*)
216                 libmagic_deployment=$(echo ${1}|cut -d= -f2)
217                 shift
218                 ;;
219         --aspell-deployment=*)
220                 aspell_deployment=$(echo ${1}|cut -d= -f2)
221                 aspell_dictionaries=$aspell_deployment
222                 shift
223                 ;;
224         --hunspell-deployment=*)
225                 hunspell_deployment=$(echo ${1}|cut -d= -f2)
226                 hunspell_dictionaries=$hunspell_deployment
227                 shift
228                 ;;
229         --thesaurus-deployment=*)
230                 thesaurus_deployment=$(echo ${1}|cut -d= -f2)
231                 shift
232                 ;;
233         --qt-deployment=*)
234                 qt_deployment=$(echo ${1}|cut -d= -f2)
235                 shift
236                 ;;
237         --with-arch=*)
238                 ARCH=$(echo ${1}|cut -d= -f2|tr ',' ' ')
239                 ARCH_LIST="${ARCH_LIST} ${ARCH}"
240                 shift
241                 ;;
242         --with-dmg-location=*)
243                 DMGLocation=$(echo ${1}|cut -d= -f2)
244                 shift
245                 ;;
246         --with-binary-strip=yes)
247                 strip="-strip"
248                 shift
249                 ;;
250         --with-build-path=*)
251                 LyxBuildDir=$(echo ${1}|cut -d= -f2)
252                 shift
253                 ;;
254         --with-util-dir=*)
255                 LyXUtilitiesDir=$(echo ${1}|cut -d= -f2)
256                 shift
257                 ;;
258         --help|--help=*)
259                 usage "${1}"
260                 ;;
261         --without-aspell)
262                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
263                 aspell_deployment="no"
264                 shift
265                 ;;
266         --without-hunspell)
267                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
268                 hunspell_deployment="no"
269                 shift
270                 ;;
271         --only-qt*=*)
272                 QtOnlyPackage=$(echo ${1}|cut -d= -f2)
273                 shift
274                 ;;
275         --only-package=*)
276                 LyxOnlyPackage=$(echo ${1}|cut -d= -f2)
277                 shift
278                 ;;
279         --enable-cxx11)
280                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
281                 EnableCXX11="--enable-cxx11"
282                 shift
283                 ;;
284         --*)
285                 LyXConfigureOptions="${LyXConfigureOptions} ${1}"
286                 shift
287                 ;;
288         *)
289                 break
290                 ;;
291         esac
292 done
293
294 if [ "${configure_qt_frameworks}" != "yes" ]; then
295         QtInstallDir=${QTDIR:-"/opt/qt4"}
296 fi
297
298 ARCH_LIST=${ARCH_LIST:-"ppc i386"}
299
300 aspellstrip=
301
302 LyxBuildDir=${LyxBuildDir:-$(dirname "${LyxSourceDir}")/lyx-build}
303 DMGLocation=${DMGLocation:-"${LyxBuildDir}"}
304
305 LyXUtilitiesDir=${LyXUtilitiesDir:-"${LyxBuildDir}"/utilities}
306
307 LibMagicSourceDir=${LIBMAGICDIR:-$(dirname "${LyxSourceDir}")/${LibMagicSource}}
308 LibMagicBuildDir="${LyxBuildDir}"/"${LibMagicSource}"
309 LibMagicInstallDir=${LibMagicInstallDir:-"${LyXUtilitiesDir}"}
310 LibMagicInstallHdr="${LibMagicInstallDir}/include/magic.h"
311
312 ASpellSourceDir=${ASPELLDIR:-$(dirname "${LyxSourceDir}")/${ASpellSource}}
313 ASpellBuildDir="${ASpellSourceDir}"
314 ASpellInstallDir=${ASpellInstallDir:-"${LyXUtilitiesDir}"}
315 ASpellInstallHdr="${ASpellInstallDir}/include/aspell.h"
316
317 HunSpellSourceDir=${HUNSPELLDIR:-$(dirname "${LyxSourceDir}")/${HunSpellSource}}
318 HunSpellBuildDir="${HunSpellSourceDir}"
319 HunSpellInstallDir=${HunSpellInstallDir:-"${LyXUtilitiesDir}"}
320 HunSpellInstallHdr="${HunSpellInstallDir}/include/hunspell/hunspell.h"
321
322 QtSourceDir=${QTSOURCEDIR:-$(dirname "${LyxSourceDir}")/${QtSourceVersion}}
323 QtBuildDir=${QtBuildDir:-"${LyxBuildDir}"/${QtBuildSubDir:-"qt-build"}}
324
325 DictionarySourceDir=${DICTIONARYDIR:-$(dirname "${LyxSourceDir}")/dictionaries}
326 DocumentationDir=$(dirname "${LyxSourceDir}")/Documents
327 DmgBackground="${LyxSourceDir}"/development/MacOSX/dmg-background.png
328
329 if [ -z "${LyXVersion}" ]; then
330         LyXVersion=$(grep AC_INIT "${LyxSourceDir}"/configure.ac | cut -d, -f2 | tr -d " []()")
331 fi
332 LyXVersionSuffix=${LyXVersionSuffix:-$(echo "${LyXVersion}" | cut -d. -f1-2)}
333 case "${LyXVersion}" in
334 *dev*)
335         LyXGitCommitHash=$(cd "${LyxSourceDir}" ; git log -1 --pretty=format:%h)
336         ;;
337 esac
338
339 LyxName="LyX"
340 LyxBase="${LyxName}-${LyXVersion}"
341 LyxApp="${LyxBase}.app"
342 LyxAppDir="${LyxBuildDir}"/"${LyxBase}"
343 LyxBuildDir="${LyxAppDir}.build"
344 LyxAppPrefix="${LyxAppDir}.app"
345 # if zip file is needed... remove the comment sign
346 #LyxAppZip="${LyxAppPrefix}.zip"
347
348 # ---------------------------------
349 # DON'T MODIFY ANYTHING BELOW HERE!
350 # ---------------------------------
351
352 # don't change order here...
353 case "${QtVersion}" in
354 5.0.*|5.1.*)
355         QtLibraries="QtSvg QtXml QtPrintSupport QtWidgets QtGui QtNetwork QtConcurrent QtCore"
356         QtFrameworkVersion="5"
357         ;;
358 5*)
359         QtLibraries="QtSvg QtXml QtPrintSupport 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 MYLDFLAGS="-mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
398
399 build_qt() {
400         echo Build Qt library ${QtSourceDir}
401         if [ "${QtInstallDir}" = "${QtBuildDir}" ]; then
402                 echo Bad install directory for Qt.
403                 echo Must be different from build directory "${QtBuildDir}".
404                 exit 1
405         fi
406         (
407                 mkdir -p "${QtBuildDir}" && cd "${QtBuildDir}"
408                 echo configure options:
409                 echo ${QtConfigureOptions} ${QTARCHS} -prefix "${QtInstallDir}"
410                 "${QtSourceDir}"/configure ${QtConfigureOptions} ${QTARCHS} -prefix "${QtInstallDir}"
411                 make -j1 && make -j1 install
412         )
413         if [ -d "${QtInstallDir}" -a ! -f "${QtInstallDir}"/include/QtCore ]; then
414                 cd "${QtInstallDir}" && (
415                         mkdir -p include
416                         cd include
417                         for libnm in ${QtLibraries} ; do
418                                 test -d ${libnm} -o -L ${libnm} || \
419                                 ( ln -s ../lib/${libnm}.framework/Headers ${libnm} && echo Link to framework ${libnm} )
420                         done
421                 )
422         fi
423 }
424
425 case ${QtOnlyPackage:-"no"} in
426 y*)
427         build_qt
428         exit 0
429         ;;
430 *)
431         if [ "${configure_qt_frameworks}" != "yes" -a -d "${QtSourceDir}" -a ! \( -d "${QtBuildDir}" -a -d "${QtInstallDir}" \) ]; then
432                 build_qt
433         fi
434         ;;
435 esac
436
437 if [ -d "${LibMagicSourceDir}" -a ! -f "${LibMagicInstallHdr}" ]; then
438         # we have a private libmagic (file(1)) source tree at hand...
439         # so let's build and install it
440         if [ -z "${LibMagicVersion}" ]; then
441                 LibMagicVersion=$(grep AC_INIT "${LibMagicSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
442         fi
443
444         LibMagicName="LibMagic"
445         LibMagicBase="${LibMagicName}-${LibMagicVersion}"
446
447         echo Build libmagic library ${LibMagicBase}
448         echo configure options:
449         echo --prefix="${LibMagicInstallDir}" ${LibMagicConfigureOptions}
450
451         mkdir -p "${LibMagicBuildDir}" && cd "${LibMagicBuildDir}"
452
453         # ----------------------------------------
454         # Build LibMagic for different architectures
455         # ----------------------------------------
456         FILE_LIST="${LibMagicLibrary}"
457
458         for arch in ${ARCH_LIST} ; do
459                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
460                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYLDFLAGS}"; export LDFLAGS
461                 "${LibMagicSourceDir}/configure"\
462                         --prefix="${LibMagicInstallDir}"\
463                         ${LibMagicConfigureOptions}
464                 make && make install${strip}
465                 for file in ${FILE_LIST} ; do
466                         if [ -f "${LibMagicInstallDir}"/lib/${file} ]; then
467                                 mv "${LibMagicInstallDir}"/lib/${file}\
468                                         "${LibMagicInstallDir}"/lib/${file}-${arch} 
469                         else
470                                 echo Cannot build and install LibMagic for ${arch}.
471                                 exit 1
472                         fi
473                 done
474         done
475         # -------------------------
476         # Create universal binaries
477         # -------------------------
478         for file in ${FILE_LIST} ; do
479                 OBJ_LIST=
480                 for arch in ${ARCH_LIST} ; do
481                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
482                 done
483                 (
484                         cd "${LibMagicInstallDir}"
485                         lipo -create ${OBJ_LIST} -o lib/${file}
486                         # check for the "missing link"...
487                         test -f lib/libmagic.dylib || (cd lib ; ln -s "${LibMagicLibrary}" libmagic.dylib)
488                 )
489         done
490         # --------
491         # Clean up
492         # --------
493         for arch in ${ARCH_LIST} ; do
494                 rm -f "${LibMagicInstallDir}"/lib/*-${arch}
495         done
496 fi
497
498 if [ -d "${HunSpellSourceDir}" -a ! -f "${HunSpellInstallHdr}" ]; then
499         # we have a private HunSpell source tree at hand...
500         # so let's build and install it
501         if [ -z "${HunSpellVersion}" ]; then
502                 HunSpellVersion=$(grep AC_INIT "${HunSpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
503         fi
504
505         HunSpellName="Hunspell"
506         HunSpellBase="${HunSpellName}-${HunSpellVersion}"
507
508         echo Build hunspell library ${HunSpellBase}
509         echo configure options:
510         echo --prefix="${HunSpellInstallDir}" ${HunspellConfigureOptions}
511
512         mkdir -p "${HunSpellBuildDir}" && cd "${HunSpellBuildDir}"
513
514         # ----------------------------------------
515         # Build HunSpell for different architectures
516         # ----------------------------------------
517         FILE_LIST="${HunSpellLibrary}"
518
519         for arch in ${ARCH_LIST} ; do
520                 make distclean
521                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
522                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYLDFLAGS}"; export LDFLAGS
523                 "${HunSpellSourceDir}/configure"\
524                         --prefix="${HunSpellInstallDir}"\
525                         ${HunspellConfigureOptions}
526                 make && make install${strip}
527                 for file in ${FILE_LIST} ; do
528                         if [ -f "${HunSpellInstallDir}"/lib/${file} ]; then
529                                 mv "${HunSpellInstallDir}"/lib/${file}\
530                                         "${HunSpellInstallDir}"/lib/${file}-${arch} 
531                         else
532                                 echo Cannot build and install HunSpell for ${arch}.
533                                 exit 1
534                         fi
535                 done
536         done
537         # -------------------------
538         # Create universal binaries
539         # -------------------------
540         for file in ${FILE_LIST} ; do
541                 OBJ_LIST=
542                 for arch in ${ARCH_LIST} ; do
543                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
544                 done
545                 (
546                         cd "${HunSpellInstallDir}"
547                         lipo -create ${OBJ_LIST} -o lib/${file}
548                         # check for the "missing link"...
549                         test -f lib/libhunspell.dylib || (cd lib ; ln -s "${HunSpellLibrary}" libhunspell.dylib)
550                 )
551         done
552         # --------
553         # Clean up
554         # --------
555         for arch in ${ARCH_LIST} ; do
556                 rm -f "${HunSpellInstallDir}"/lib/*-${arch}
557         done
558 fi
559
560 if [ -d "${ASpellSourceDir}" -a ! -f "${ASpellInstallHdr}" -a "yes" = "${aspell_deployment}" ]; then
561         # we have a private ASpell source tree at hand...
562         # so let's build and install it
563         if [ -z "${ASpellVersion}" ]; then
564                 ASpellVersion=$(grep AC_INIT "${ASpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
565         fi
566
567         ASpellName="Aspell"
568         ASpellBase="${ASpellName}-${ASpellVersion}"
569
570         echo Build aspell library ${ASpellBase}
571         echo configure options:
572         echo --prefix="${ASpellInstallDir}" ${AspellConfigureOptions}
573
574         # ASpell builds inplace only :(
575         cd "${ASpellSourceDir}"
576
577         # ----------------------------------------
578         # Build ASpell for different architectures
579         # ----------------------------------------
580         FILE_LIST="${ASpellLibrary}"
581
582         for arch in ${ARCH_LIST} ; do
583                 make distclean
584                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
585                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYLDFLAGS}"; export LDFLAGS
586                 CXXFLAGS=-g "${ASpellSourceDir}/configure"\
587                         --prefix="${ASpellInstallDir}"\
588                         ${AspellConfigureOptions}
589                 make && make install${aspellstrip}
590                 for file in ${FILE_LIST} ; do
591                         if [ -f "${ASpellInstallDir}"/lib/${file} ]; then
592                                 mv "${ASpellInstallDir}"/lib/${file}\
593                                         "${ASpellInstallDir}"/lib/${file}-${arch} 
594                         else
595                                 echo Cannot build and install ASpell for ${arch}.
596                                 exit 1
597                         fi
598                 done
599         done
600         # -------------------------
601         # Create universal binaries
602         # -------------------------
603         for file in ${FILE_LIST} ; do
604                 OBJ_LIST=
605                 for arch in ${ARCH_LIST} ; do
606                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
607                 done
608                 (
609                         cd "${ASpellInstallDir}"
610                         lipo -create ${OBJ_LIST} -o lib/${file}
611                 )
612         done
613         # --------
614         # Clean up
615         # --------
616         for arch in ${ARCH_LIST} ; do
617                 rm -f "${ASpellInstallDir}"/lib/*-${arch}
618         done
619 fi
620
621
622 framework_name() {
623         echo "Frameworks/${1}.framework"
624 }
625
626 LYX_FILE_LIST="lyx lyxclient tex2lyx lyxconvert"
627 BUNDLE_PATH="Contents/MacOS"
628 LYX_BUNDLE_PATH="${LyxAppPrefix}/${BUNDLE_PATH}"
629 build_lyx() {
630         # Clear Output
631         if [ -n "${LyxAppZip}" -a -f "${LyxAppZip}" ]; then rm "${LyxAppZip}"; fi
632         if [ -d "${LyxAppPrefix}" ]; then rm -rf "${LyxAppPrefix}"; fi
633
634         case "${EnableCXX11}" in
635         "--enable-cxx11")
636                 export CC=cc
637                 export CXX="c++ -stdlib=libc++"
638                 export CXXFLAGS=-std=c++11
639                 ;;
640         esac
641
642         # -------------------------------------
643         # Automate configure check
644         # -------------------------------------
645         if [ ! -f "${LyxSourceDir}"/configure -o "${LyxSourceDir}"/configure -ot "${LyxSourceDir}"/configure.ac ]; then
646                 ( cd "${LyxSourceDir}" && sh autogen.sh )
647         else
648                 find "${LyxSourceDir}" -name Makefile.am -print | while read file ; do
649                         dname=$(dirname "$file")
650                         if [ -f "$dname/Makefile.in" -a "$dname/Makefile.in" -ot "$file" ]; then
651                                 ( cd "${LyxSourceDir}" && sh autogen.sh )
652                                 break
653                         fi
654                 done
655         fi
656         # -------------------------------------
657         # Build LyX for different architectures
658         # -------------------------------------
659
660         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_deployment}" ]; then
661                 ConfigureExtraInc="--with-extra-inc=${ASpellInstallDir}/include"
662                 ConfigureExtraLib="--with-extra-lib=${ASpellInstallDir}/lib"
663         fi
664
665         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_deployment}" ]; then
666                 HunSpellFramework=$(framework_name Hunspell)
667                 HunSpellFramework=$(basename "${HunSpellFramework}")
668                 ConfigureExtraInc="--with-extra-inc=${HunSpellInstallDir}/include"
669                 ConfigureExtraLib="--with-extra-lib=${HunSpellInstallDir}/lib"
670                 # LyXConfigureOptions="${LyXConfigureOptions} --with-hunspell-framework=${HunSpellFramework}"
671         fi
672         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraInc}"
673         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraLib}"
674
675         for arch in ${ARCH_LIST} ; do
676
677                 if [ -d "${LyxBuildDir}" ];  then rm -r "${LyxBuildDir}"; fi
678                 mkdir -p "${LyxBuildDir}" && cd "${LyxBuildDir}"
679
680                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
681                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYLDFLAGS}"
682
683                 if [ "$configure_qt_frameworks" = "yes" ]; then
684                         export QT_CORE_CFLAGS="-FQtCore"
685                         export QT_CORE_LIBS="-framework QtCore"
686                         export QT_FRONTEND_CFLAGS="-FQtGui"
687                         export QT_FRONTEND_LIBS="-framework QtGui"
688                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtCore.framework/Headers"
689                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtGui.framework/Headers"
690                 fi
691
692                 echo LDFLAGS="${LDFLAGS}"
693                 export LDFLAGS
694                 echo CPPFLAGS="${CPPFLAGS}"
695                 export CPPFLAGS
696                 echo CONFIGURE_OPTIONS="${LyXConfigureOptions}" ${QtInstallDir:+"--with-qt-dir=${QtInstallDir}"}
697                 "${LyxSourceDir}/configure"\
698                         --prefix="${LyxAppPrefix}" --with-version-suffix="-${LyXVersionSuffix}"\
699                         ${QtInstallDir:+"--with-qt-dir=${QtInstallDir}"} \
700                         ${LyXConfigureOptions}\
701                         --enable-build-type=rel && \
702                 make ${MAKEJOBS} && make install${strip}
703                 for file in ${LYX_FILE_LIST} ; do
704                         if [ -f "${LYX_BUNDLE_PATH}/${file}" ]; then
705                                 mv "${LYX_BUNDLE_PATH}/${file}"\
706                                         "${LYX_BUNDLE_PATH}/${file}-${arch}" 
707                         else
708                                 echo ERROR: Cannot build and install ${file} for ${arch}.
709                                 exit 1
710                         fi
711                 done
712         done
713 }
714
715 content_directory() {
716         target="$1"
717         content=$(dirname "${target}")
718         content=$(dirname "${content}")
719         echo "${content}"
720 }
721
722 installname() {
723                 echo install_name_tool "$@"
724                 install_name_tool "$@" || exit 1
725 }
726
727 private_framework() {
728         fwdir=$(framework_name "$1")
729         source="$2"
730         target="$3"
731         condir=$(content_directory "${target}")
732         libnm=$(basename "${source}")
733         mkdir -p "${condir}/${fwdir}"
734         if [ ! -f "${condir}/${fwdir}/${libnm}" ]; then
735                 cp -p "${source}" "${condir}/${fwdir}"
736                 installname -id "@executable_path/../${fwdir}/${libnm}" "${condir}/${fwdir}/${libnm}"
737         fi
738         installname -change "${source}" "@executable_path/../${fwdir}/${libnm}" "${target}"
739 }
740
741 deploy_qtlibs() {
742         source="${QtInstallDir}"
743         target="$1"
744         version="Versions/${QtFrameworkVersion}/"
745         condir=$(content_directory "${target}")
746         mkdir -p "${condir}/Resources"
747         test -f "${condir}/Resources/qt.conf" || cat - > "${condir}/Resources/qt.conf" <<-EOF
748 [Paths]
749 Plugins = PlugIns
750 Translations = translations
751 EOF
752         if [ ! -d "${condir}/PlugIns" ]; then
753                 mkdir -p "${condir}/PlugIns"
754                 find "${source}/plugins" -name \*.dylib -print | grep -v _debug.dylib | while read libname ; do
755                         echo Copy plugin "${libname}"
756                         dylib=$(basename "${libname}")
757                         dirname=$(dirname "${libname}")
758                         dirname=$(basename "${dirname}")
759                         mkdir -p "${condir}/PlugIns/${dirname}"
760                         cp -p "${libname}" "${condir}/PlugIns/${dirname}"
761                 done
762         fi
763         for libnm in ${QtLibraries} ; do
764                 fwdir=$(framework_name "$libnm")
765                 dirname=$(dirname "${fwdir}")
766                 mkdir -p "${condir}/${dirname}"
767                 dirname=$(basename "${fwdir}")
768                 test -d "${condir}/${fwdir}" || (
769                         echo Copy framework "${source}/lib/"$(basename "${fwdir}")
770                         cp -pR "${source}/lib/"$(basename "${fwdir}") "${condir}/${fwdir}"
771                         rm -f "${condir}/${fwdir}/${version}${libnm}"_debug
772                         installname -id "@executable_path/../${fwdir}/${version}${libnm}" "${condir}/${fwdir}/${version}${libnm}"
773                         find "${condir}/PlugIns" "${condir}/"$(dirname "${fwdir}") -name Headers -prune -o -type f -print | while read filename ; do
774                                 if [ "${filename}" != "${target}" ]; then
775                                         otool -L "${filename}" 2>/dev/null | sort -u | while read library ; do
776                                                 # pattern match for: /path/to/qt/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.6.0, current version 4.6.2)
777                                                 case "${library}" in
778                                                 *@rpath/*"${libnm}"*"("*version*")"*)
779                                                         # echo rpath based name for ${libnm} is ok.
780                                                         ;;
781                                                 *"${libnm}"*"("*version*")"*)
782                                                         installname -change\
783                                                                 "${source}/lib/${dirname}/${version}${libnm}"\
784                                                                 "@executable_path/../${fwdir}/${version}${libnm}"\
785                                                                 "${filename}"
786                                                         ;;
787                                                 esac
788                                         done
789                                 fi
790                         done
791                 )
792                 installname -change\
793                         "${source}/lib/${dirname}/${version}${libnm}"\
794                         "@executable_path/../${fwdir}/${version}${libnm}"\
795                         "${target}"
796         done
797         if [ -d "${source}"/translations ]; then
798                 if [ ! -d "${condir}/translations" ]; then
799                         mkdir -p "${condir}/translations"
800                 fi
801                 echo Copy Qt translations to "${condir}/translations"
802                 cp -p "${source}"/translations/qt_*.qm "${condir}/translations"
803         fi
804 }
805
806 # -------------------------
807 # Create universal binaries
808 # -------------------------
809 convert_universal() {
810         cd "${LyxAppPrefix}"
811         for file in ${LYX_FILE_LIST} ; do
812                 OBJ_LIST=
813                 for arch in ${ARCH_LIST} ; do
814                         if [ -f "${BUNDLE_PATH}/${file}-${arch}" ]; then
815                                 OBJ_LIST="${OBJ_LIST} ${BUNDLE_PATH}/${file}-${arch}"
816                         fi
817                 done
818                 if [ -n "${OBJ_LIST}" ]; then
819                         lipo -create ${OBJ_LIST} -o "${BUNDLE_PATH}/${file}"
820                 fi
821                 if [ -f "${LibMagicInstallDir}/lib/${LibMagicLibrary}" -a "yes" = "${libmagic_deployment}" ]; then
822                         private_framework LibMagic "${LibMagicInstallDir}/lib/${LibMagicLibrary}" "${LYX_BUNDLE_PATH}/${file}"
823                 fi
824                 if [ -f "${ASpellInstallDir}/lib/${ASpellLibrary}" -a "yes" = "${aspell_deployment}" ]; then
825                         private_framework Aspell "${ASpellInstallDir}/lib/${ASpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
826                 fi
827                 if [ -f "${HunSpellInstallDir}/lib/${HunSpellLibrary}" -a "yes" = "${hunspell_deployment}" ]; then
828                         private_framework Hunspell "${HunSpellInstallDir}/lib/${HunSpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
829                 fi
830                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
831                         deploy_qtlibs "${LYX_BUNDLE_PATH}/${file}"
832                 fi
833                 otool -L "${BUNDLE_PATH}/${file}" | while read reference ; do
834                         case "${reference}" in
835                         *"${LyxBuildDir}"*"("*")")
836                                 echo ERROR: Bad reference to "${reference}" found!!
837                                 ;;
838                         esac
839                 done
840         done
841         for arch in ${ARCH_LIST} ; do
842                 rm -f ${BUNDLE_PATH}/*-${arch}
843         done
844 }
845
846 deduplicate() {
847         find "$@" -type f -print | while read file ; do
848                 echo $(md5 -q "$file") "$file"
849         done | sort | while read hash file ; do
850                 ppath=$(dirname "$pfile")
851                 path=$(dirname "$file")
852                 if [ "$phash" = "$hash" -a "$ppath" = "$path" ]; then
853                         pname=$(basename "$pfile")
854                         name=$(basename "$file")
855                         cmp -s "$pfile" "$file" && (
856                                 rm "$file"
857                                 cd "$path" && ln -s "$pname" "$name" && echo link for "$file" created
858                         )
859                 fi
860                 phash="$hash"
861                 pfile="$file"
862         done
863 }
864
865 copy_dictionaries() {
866         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_dictionaries}" ]; then
867                 ASpellResources="${LyxAppPrefix}/Contents/Resources"
868                 # try to reuse macports dictionaries for now
869                 if [ -d /opt/local/lib/aspell-0.60 ]; then ASpellInstallDir=/opt/local ; fi
870                 mkdir -p "${ASpellResources}"
871                 echo Copy Aspell dictionaries from "${ASpellInstallDir}"
872                 mkdir -p "${ASpellResources}"/data "${ASpellResources}"/dicts
873                 cp -p -r "${ASpellInstallDir}/lib/aspell-0.60"/* "${ASpellResources}"/data
874                 cp -p -r "${ASpellInstallDir}/share/aspell"/* "${ASpellResources}"/dicts
875         fi
876         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_dictionaries}" ]; then
877                 HunSpellResources="${LyxAppPrefix}/Contents/Resources"
878                 if [ -d "${DictionarySourceDir}" ]; then
879                         ( cd "${DictionarySourceDir}" && find dicts -name .svn -prune -o -type f -print | cpio -pmdv "${HunSpellResources}" )
880                         deduplicate "${HunSpellResources}"/dicts
881                 fi
882         fi
883         if [ -d "${DictionarySourceDir}" -a "yes" = "${thesaurus_deployment}" ]; then
884                 MyThesResources="${LyxAppPrefix}/Contents/Resources"
885                 ( cd "${DictionarySourceDir}" && find thes -name .svn -prune -o -type f -print | cpio -pmdv "${MyThesResources}" )
886                 deduplicate "${MyThesResources}"/thes
887         fi
888 }
889
890 set_bundle_display_options() {
891         X_BOUNDS=$2
892         Y_BOUNDS=$3
893         Y_POSITION=$((Y_BOUNDS - 65))
894         Y_BOUNDS=$((Y_BOUNDS + 20))
895         LYX_X_POSITION=$((X_BOUNDS / 4))
896         LYX_Y_POSITION=$Y_POSITION
897         APP_X_POSITION=$((3 * X_BOUNDS / 4))
898         APP_Y_POSITION=$Y_POSITION
899         WITH_DOCUMENTS=$(test -d "${1}/Documents" && echo true || echo false)
900         osascript <<-EOF
901         tell application "Finder"
902         set f to POSIX file ("${1}" as string) as alias
903         tell folder f
904             open
905             tell container window
906                 set toolbar visible to false
907                 set statusbar visible to false
908                 set current view to icon view
909                 delay 1 -- sync
910                 set the bounds to {20, 50, $X_BOUNDS, $Y_BOUNDS}
911             end tell
912             delay 1 -- sync
913             set icon size of the icon view options of container window to 64
914             set arrangement of the icon view options of container window to not arranged
915             if ${WITH_DOCUMENTS} then
916                set position of item "Documents" to {$LYX_X_POSITION,0}
917             end if
918             set position of item "${LyxName}.app" to {$LYX_X_POSITION,$LYX_Y_POSITION}
919             set position of item "Applications" to {$APP_X_POSITION,$APP_Y_POSITION}
920             set background picture of the icon view options\
921                of container window to file "background.png" of folder "Pictures"
922             set the bounds of the container window to {0, 0, $X_BOUNDS, $Y_BOUNDS}
923             update without registering applications
924             delay 5 -- sync
925             close
926         end tell
927         delay 5 -- sync
928     end tell
929 EOF
930 }
931
932 make_dmg() {
933         cd "${1}"
934
935         BGSIZE=$(file "$DmgBackground" | awk -F , '/PNG/{print $2 }' | tr x ' ')
936         BG_W=$(echo ${BGSIZE} | awk '{print $1 }')
937         BG_H=$(echo ${BGSIZE} | awk '{print $2 }')
938
939         rm -f "${DMGNAME}.sparseimage" "${DMGNAME}.dmg"
940
941         hdiutil create -type SPARSE -size ${DMGSIZE:-"250m"} -fs HFS+ -volname "${LyxBase}" "${DMGNAME}"
942         # Unmount currently mounted disk image
943         mount | grep "${LyxBase}" && umount /Volumes/"${LyxBase}"
944         test -d /Volumes/"${LyxBase}" && rmdir /Volumes/"${LyxBase}"
945
946         # Mount the disk image
947         DEVICES=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
948
949         # Obtain device information
950         DEVICE=$(echo $DEVICES | cut -f 1 -d ' ')
951         VOLUME=$(mount |grep ${DEVICE} | cut -f 3 -d ' ')
952
953         # copy in the application bundle
954         ditto --hfsCompression "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
955
956         # copy in background image
957         mkdir -p "${VOLUME}/Pictures"
958         ditto --hfsCompression "${DmgBackground}" "${VOLUME}/Pictures/background.png"
959         # symlink applications
960         ln -s /Applications/ "${VOLUME}"/Applications
961         test -d "${DocumentationDir}" && ditto --hfsCompression "${DocumentationDir}" "${VOLUME}"
962         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
963         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
964         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
965
966         # Unmount the disk image
967         hdiutil detach ${DEVICE}
968
969         # Convert the disk image to read-only
970         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
971         rm -f "${DMGNAME}.sparseimage"
972 }
973
974 # ------------------------------
975 # Building distribution packages
976 # ------------------------------
977
978 build_package() {
979         test -n "${LyxAppZip}" && (
980                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
981         )
982
983         DMGARCH=""
984         for arch in ${ARCH_LIST} ; do
985                 DMGARCH="${DMGARCH}-${arch}"
986         done
987         QtDmgArchSuffix=${QtMajorVersion}${DMGARCH}${QtAPI}.dmg
988
989         test -n "${DMGLocation}" && (
990                 make_dmg "${DMGLocation}"
991                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
992                         rm -f "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
993                         echo move to "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
994                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
995                 fi
996         )
997 }
998
999 # ------------------------------
1000 # main block
1001 # ------------------------------
1002
1003 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
1004         build_lyx
1005         convert_universal
1006         copy_dictionaries
1007 fi
1008 build_package