]> git.lyx.org Git - lyx.git/blob - development/LyX-Mac-binary-release.sh
Use data from src/lyxwinres.rc to generate lyx.coff for the Windows
[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
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 lyxconvert"
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         case "${EnableCXX11}" in
634         "--enable-cxx11")
635                 export CC=cc
636                 export CXX="c++ -stdlib=libc++"
637                 export CXXFLAGS=-std=c++11
638                 ;;
639         esac
640
641         # -------------------------------------
642         # Automate configure check
643         # -------------------------------------
644         if [ ! -f "${LyxSourceDir}"/configure -o "${LyxSourceDir}"/configure -ot "${LyxSourceDir}"/configure.ac ]; then
645                 ( cd "${LyxSourceDir}" && sh autogen.sh )
646         else
647                 find "${LyxSourceDir}" -name Makefile.am -print | while read file ; do
648                         dname=$(dirname "$file")
649                         if [ -f "$dname/Makefile.in" -a "$dname/Makefile.in" -ot "$file" ]; then
650                                 ( cd "${LyxSourceDir}" && sh autogen.sh )
651                                 break
652                         fi
653                 done
654         fi
655         # -------------------------------------
656         # Build LyX for different architectures
657         # -------------------------------------
658
659         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_deployment}" ]; then
660                 ConfigureExtraInc="--with-extra-inc=${ASpellInstallDir}/include"
661                 ConfigureExtraLib="--with-extra-lib=${ASpellInstallDir}/lib"
662         fi
663
664         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_deployment}" ]; then
665                 HunSpellFramework=$(framework_name Hunspell)
666                 HunSpellFramework=$(basename "${HunSpellFramework}")
667                 ConfigureExtraInc="--with-extra-inc=${HunSpellInstallDir}/include"
668                 ConfigureExtraLib="--with-extra-lib=${HunSpellInstallDir}/lib"
669                 # LyXConfigureOptions="${LyXConfigureOptions} --with-hunspell-framework=${HunSpellFramework}"
670         fi
671         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraInc}"
672         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraLib}"
673
674         for arch in ${ARCH_LIST} ; do
675
676                 if [ -d "${LyxBuildDir}" ];  then rm -r "${LyxBuildDir}"; fi
677                 mkdir -p "${LyxBuildDir}" && cd "${LyxBuildDir}"
678
679                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
680                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
681
682                 if [ "$configure_qt_frameworks" = "yes" ]; then
683                         export QT_CORE_CFLAGS="-FQtCore"
684                         export QT_CORE_LIBS="-framework QtCore"
685                         export QT_FRONTEND_CFLAGS="-FQtGui"
686                         export QT_FRONTEND_LIBS="-framework QtGui"
687                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtCore.framework/Headers"
688                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtGui.framework/Headers"
689                 fi
690
691                 echo LDFLAGS="${LDFLAGS}"
692                 export LDFLAGS
693                 echo CPPFLAGS="${CPPFLAGS}"
694                 export CPPFLAGS
695                 echo CONFIGURE_OPTIONS="${LyXConfigureOptions}" ${QtInstallDir:+"--with-qt-dir=${QtInstallDir}"}
696                 "${LyxSourceDir}/configure"\
697                         --prefix="${LyxAppPrefix}" --with-version-suffix="-${LyXVersionSuffix}"\
698                         ${QtInstallDir:+"--with-qt-dir=${QtInstallDir}"} \
699                         ${LyXConfigureOptions}\
700                         --enable-build-type=rel && \
701                 make ${MAKEJOBS} && make install${strip}
702                 for file in ${LYX_FILE_LIST} ; do
703                         if [ -f "${LYX_BUNDLE_PATH}/${file}" ]; then
704                                 mv "${LYX_BUNDLE_PATH}/${file}"\
705                                         "${LYX_BUNDLE_PATH}/${file}-${arch}" 
706                         else
707                                 echo ERROR: Cannot build and install ${file} for ${arch}.
708                                 exit 1
709                         fi
710                 done
711         done
712 }
713
714 content_directory() {
715         target="$1"
716         content=$(dirname "${target}")
717         content=$(dirname "${content}")
718         echo "${content}"
719 }
720
721 installname() {
722                 echo install_name_tool "$@"
723                 install_name_tool "$@" || exit 1
724 }
725
726 private_framework() {
727         fwdir=$(framework_name "$1")
728         source="$2"
729         target="$3"
730         condir=$(content_directory "${target}")
731         libnm=$(basename "${source}")
732         mkdir -p "${condir}/${fwdir}"
733         if [ ! -f "${condir}/${fwdir}/${libnm}" ]; then
734                 cp -p "${source}" "${condir}/${fwdir}"
735                 installname -id "@executable_path/../${fwdir}/${libnm}" "${condir}/${fwdir}/${libnm}"
736         fi
737         installname -change "${source}" "@executable_path/../${fwdir}/${libnm}" "${target}"
738 }
739
740 deploy_qtlibs() {
741         source="${QtInstallDir}"
742         target="$1"
743         version="Versions/${QtFrameworkVersion}/"
744         condir=$(content_directory "${target}")
745         mkdir -p "${condir}/Resources"
746         test -f "${condir}/Resources/qt.conf" || cat - > "${condir}/Resources/qt.conf" <<-EOF
747 [Paths]
748 Plugins = PlugIns
749 Translations = translations
750 EOF
751         if [ ! -d "${condir}/PlugIns" ]; then
752                 mkdir -p "${condir}/PlugIns"
753                 find "${source}/plugins" -name \*.dylib -print | grep -v _debug.dylib | while read libname ; do
754                         echo Copy plugin "${libname}"
755                         dylib=$(basename "${libname}")
756                         dirname=$(dirname "${libname}")
757                         dirname=$(basename "${dirname}")
758                         mkdir -p "${condir}/PlugIns/${dirname}"
759                         cp -p "${libname}" "${condir}/PlugIns/${dirname}"
760                 done
761         fi
762         for libnm in ${QtLibraries} ; do
763                 fwdir=$(framework_name "$libnm")
764                 dirname=$(dirname "${fwdir}")
765                 mkdir -p "${condir}/${dirname}"
766                 dirname=$(basename "${fwdir}")
767                 test -d "${condir}/${fwdir}" || (
768                         echo Copy framework "${source}/lib/"$(basename "${fwdir}")
769                         cp -pR "${source}/lib/"$(basename "${fwdir}") "${condir}/${fwdir}"
770                         rm -f "${condir}/${fwdir}/${version}${libnm}"_debug
771                         installname -id "@executable_path/../${fwdir}/${version}${libnm}" "${condir}/${fwdir}/${version}${libnm}"
772                         find "${condir}/PlugIns" "${condir}/"$(dirname "${fwdir}") -name Headers -prune -o -type f -print | while read filename ; do
773                                 if [ "${filename}" != "${target}" ]; then
774                                         otool -L "${filename}" 2>/dev/null | sort -u | while read library ; do
775                                                 # pattern match for: /path/to/qt/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.6.0, current version 4.6.2)
776                                                 case "${library}" in
777                                                 *@rpath/*"${libnm}"*"("*version*")"*)
778                                                         echo rpath based name for ${libnm} is ok.
779                                                         ;;
780                                                 *"${libnm}"*"("*version*")"*)
781                                                         installname -change\
782                                                                 "${source}/lib/${dirname}/${version}${libnm}"\
783                                                                 "@executable_path/../${fwdir}/${version}${libnm}"\
784                                                                 "${filename}"
785                                                         ;;
786                                                 esac
787                                         done
788                                 fi
789                         done
790                 )
791                 installname -change\
792                         "${source}/lib/${dirname}/${version}${libnm}"\
793                         "@executable_path/../${fwdir}/${version}${libnm}"\
794                         "${target}"
795         done
796         if [ -d "${source}"/translations ]; then
797                 if [ ! -d "${condir}/translations" ]; then
798                         mkdir -p "${condir}/translations"
799                 fi
800                 echo Copy Qt translations to "${condir}/translations"
801                 cp -p "${source}"/translations/qt_*.qm "${condir}/translations"
802         fi
803 }
804
805 # -------------------------
806 # Create universal binaries
807 # -------------------------
808 convert_universal() {
809         cd "${LyxAppPrefix}"
810         for file in ${LYX_FILE_LIST} ; do
811                 OBJ_LIST=
812                 for arch in ${ARCH_LIST} ; do
813                         if [ -f "${BUNDLE_PATH}/${file}-${arch}" ]; then
814                                 OBJ_LIST="${OBJ_LIST} ${BUNDLE_PATH}/${file}-${arch}"
815                         fi
816                 done
817                 if [ -n "${OBJ_LIST}" ]; then
818                         lipo -create ${OBJ_LIST} -o "${BUNDLE_PATH}/${file}"
819                 fi
820                 if [ -f "${LibMagicInstallDir}/lib/${LibMagicLibrary}" -a "yes" = "${libmagic_deployment}" ]; then
821                         private_framework LibMagic "${LibMagicInstallDir}/lib/${LibMagicLibrary}" "${LYX_BUNDLE_PATH}/${file}"
822                 fi
823                 if [ -f "${ASpellInstallDir}/lib/${ASpellLibrary}" -a "yes" = "${aspell_deployment}" ]; then
824                         private_framework Aspell "${ASpellInstallDir}/lib/${ASpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
825                 fi
826                 if [ -f "${HunSpellInstallDir}/lib/${HunSpellLibrary}" -a "yes" = "${hunspell_deployment}" ]; then
827                         private_framework Hunspell "${HunSpellInstallDir}/lib/${HunSpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
828                 fi
829                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
830                         deploy_qtlibs "${LYX_BUNDLE_PATH}/${file}"
831                 fi
832                 otool -L "${BUNDLE_PATH}/${file}" | while read reference ; do
833                         case "${reference}" in
834                         *"${LyxBuildDir}"*"("*")")
835                                 echo ERROR: Bad reference to "${reference}" found!!
836                                 ;;
837                         esac
838                 done
839         done
840         for arch in ${ARCH_LIST} ; do
841                 rm -f ${BUNDLE_PATH}/*-${arch}
842         done
843 }
844
845 deduplicate() {
846         find "$@" -type f -print | while read file ; do
847                 echo $(md5 -q "$file") "$file"
848         done | sort | while read hash file ; do
849                 ppath=$(dirname "$pfile")
850                 path=$(dirname "$file")
851                 if [ "$phash" = "$hash" -a "$ppath" = "$path" ]; then
852                         pname=$(basename "$pfile")
853                         name=$(basename "$file")
854                         cmp -s "$pfile" "$file" && (
855                                 rm "$file"
856                                 cd "$path" && ln -s "$pname" "$name" && echo link for "$file" created
857                         )
858                 fi
859                 phash="$hash"
860                 pfile="$file"
861         done
862 }
863
864 copy_dictionaries() {
865         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_dictionaries}" ]; then
866                 ASpellResources="${LyxAppPrefix}/Contents/Resources"
867                 # try to reuse macports dictionaries for now
868                 if [ -d /opt/local/lib/aspell-0.60 ]; then ASpellInstallDir=/opt/local ; fi
869                 mkdir -p "${ASpellResources}"
870                 echo Copy Aspell dictionaries from "${ASpellInstallDir}"
871                 mkdir -p "${ASpellResources}"/data "${ASpellResources}"/dicts
872                 cp -p -r "${ASpellInstallDir}/lib/aspell-0.60"/* "${ASpellResources}"/data
873                 cp -p -r "${ASpellInstallDir}/share/aspell"/* "${ASpellResources}"/dicts
874         fi
875         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_dictionaries}" ]; then
876                 HunSpellResources="${LyxAppPrefix}/Contents/Resources"
877                 if [ -d "${DictionarySourceDir}" ]; then
878                         ( cd "${DictionarySourceDir}" && find dicts -name .svn -prune -o -type f -print | cpio -pmdv "${HunSpellResources}" )
879                         deduplicate "${HunSpellResources}"/dicts
880                 fi
881         fi
882         if [ -d "${DictionarySourceDir}" -a "yes" = "${thesaurus_deployment}" ]; then
883                 MyThesResources="${LyxAppPrefix}/Contents/Resources"
884                 ( cd "${DictionarySourceDir}" && find thes -name .svn -prune -o -type f -print | cpio -pmdv "${MyThesResources}" )
885                 deduplicate "${MyThesResources}"/thes
886         fi
887 }
888
889 set_bundle_display_options() {
890         X_BOUNDS=$2
891         Y_BOUNDS=$3
892         Y_POSITION=$((Y_BOUNDS - 65))
893         Y_BOUNDS=$((Y_BOUNDS + 20))
894         LYX_X_POSITION=$((X_BOUNDS / 4))
895         LYX_Y_POSITION=$Y_POSITION
896         APP_X_POSITION=$((3 * X_BOUNDS / 4))
897         APP_Y_POSITION=$Y_POSITION
898         WITH_DOCUMENTS=$(test -d "${1}/Documents" && echo true || echo false)
899         osascript <<-EOF
900         tell application "Finder"
901         set f to POSIX file ("${1}" as string) as alias
902         tell folder f
903             open
904             tell container window
905                 set toolbar visible to false
906                 set statusbar visible to false
907                 set current view to icon view
908                 delay 1 -- sync
909                 set the bounds to {20, 50, $X_BOUNDS, $Y_BOUNDS}
910             end tell
911             delay 1 -- sync
912             set icon size of the icon view options of container window to 64
913             set arrangement of the icon view options of container window to not arranged
914             if ${WITH_DOCUMENTS} then
915                set position of item "Documents" to {$LYX_X_POSITION,0}
916             end if
917             set position of item "${LyxName}.app" to {$LYX_X_POSITION,$LYX_Y_POSITION}
918             set position of item "Applications" to {$APP_X_POSITION,$APP_Y_POSITION}
919             set background picture of the icon view options\
920                of container window to file "background.png" of folder "Pictures"
921             set the bounds of the container window to {0, 0, $X_BOUNDS, $Y_BOUNDS}
922             update without registering applications
923             delay 5 -- sync
924             close
925         end tell
926         delay 5 -- sync
927     end tell
928 EOF
929 }
930
931 make_dmg() {
932         cd "${1}"
933
934         BGSIZE=$(file "$DmgBackground" | awk -F , '/PNG/{print $2 }' | tr x ' ')
935         BG_W=$(echo ${BGSIZE} | awk '{print $1 }')
936         BG_H=$(echo ${BGSIZE} | awk '{print $2 }')
937
938         rm -f "${DMGNAME}.sparseimage" "${DMGNAME}.dmg"
939
940         hdiutil create -type SPARSE -size ${DMGSIZE:-"250m"} -fs HFS+ -volname "${LyxBase}" "${DMGNAME}"
941         # Unmount currently mounted disk image
942         mount | grep "${LyxBase}" && umount /Volumes/"${LyxBase}"
943         test -d /Volumes/"${LyxBase}" && rmdir /Volumes/"${LyxBase}"
944
945         # Mount the disk image
946         DEVICES=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
947
948         # Obtain device information
949         DEVICE=$(echo $DEVICES | cut -f 1 -d ' ')
950         VOLUME=$(mount |grep ${DEVICE} | cut -f 3 -d ' ')
951
952         # copy in the application bundle
953         ditto --hfsCompression "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
954
955         # copy in background image
956         mkdir -p "${VOLUME}/Pictures"
957         ditto --hfsCompression "${DmgBackground}" "${VOLUME}/Pictures/background.png"
958         # symlink applications
959         ln -s /Applications/ "${VOLUME}"/Applications
960         test -d "${DocumentationDir}" && ditto --hfsCompression "${DocumentationDir}" "${VOLUME}"
961         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
962         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
963         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
964
965         # Unmount the disk image
966         hdiutil detach ${DEVICE}
967
968         # Convert the disk image to read-only
969         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
970         rm -f "${DMGNAME}.sparseimage"
971 }
972
973 # ------------------------------
974 # Building distribution packages
975 # ------------------------------
976
977 build_package() {
978         test -n "${LyxAppZip}" && (
979                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
980         )
981
982         DMGARCH=""
983         for arch in ${ARCH_LIST} ; do
984                 DMGARCH="${DMGARCH}-${arch}"
985         done
986         QtDmgArchSuffix=${QtMajorVersion}${DMGARCH}${QtAPI}.dmg
987
988         test -n "${DMGLocation}" && (
989                 make_dmg "${DMGLocation}"
990                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt_deployment}" ]; then
991                         rm -f "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
992                         echo move to "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
993                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+${QtDmgArchSuffix}"
994                 fi
995         )
996 }
997
998 # ------------------------------
999 # main block
1000 # ------------------------------
1001
1002 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
1003         build_lyx
1004         convert_universal
1005         copy_dictionaries
1006 fi
1007 build_package