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