]> git.lyx.org Git - lyx.git/blob - development/LyX-Mac-binary-release.sh
moveColumn now also swaps column_info
[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="no"
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 # pkg-config is not usable with this script
332 export PKG_CONFIG=""
333
334 # These variables define the identifiers of the
335 # system (both Intel and PowerPC) to compile for.
336 # (Note: darwin8 is 10.4; darwin9 is 10.5.)
337 # Only change these if necessary
338
339 HostSystem_i386="i686-apple-darwin8"
340 HostSystem_ppc="powerpc-apple-darwin8"
341
342 if [ "${configure_qt4_frameworks}" != "yes" -a -d "${Qt4SourceDir}" -a ! \( -d "${Qt4BuildDir}" -a -d "${QtInstallDir}" \) ]; then
343         echo Build Qt4 library ${Qt4SourceDir}
344         if [ "${QtInstallDir}" = "${Qt4BuildDir}" ]; then
345                 echo Bad install directory for Qt.
346                 echo Must be different from build directory "${Qt4BuildDir}".
347                 exit 1
348         fi
349         (
350                 mkdir -p "${Qt4BuildDir}" && cd "${Qt4BuildDir}"
351                 for arch in ${ARCH_LIST} ; do
352                         ARCHS="${ARCHS} -arch ${arch}"
353                 done
354                 echo configure options:
355                 echo ${Qt4ConfigureOptions} ${ARCHS} -prefix "${QtInstallDir}"
356                 echo yes | "${Qt4SourceDir}"/configure ${Qt4ConfigureOptions} ${ARCHS} -prefix "${QtInstallDir}"
357                 make ${MAKEJOBS} && make install
358         )
359         cd "${QtInstallDir}" && (
360                 mkdir -p include
361                 cd include
362                 for libnm in ${QtLibraries} ; do
363                         test -d ${libnm} -o -L ${libnm} || ln -s ../lib/${libnm}.framework/Headers ${libnm}
364                 done
365         )
366 fi
367
368 if [ -d "${GettextSourceDir}" -a ! -f "${GettextInstallHdr}" ]; then
369         # we have a private Gettext source tree at hand...
370         # so let's build and install it
371         if [ -z "${GettextVersion}" ]; then
372                 GettextVersion=$(grep AC_INIT "${GettextSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
373         fi
374
375         GettextName="Gettext"
376         GettextBase="${GettextName}-${GettextVersion}"
377
378         echo Build gettext library ${GettextBase}
379         echo configure options:
380         echo --prefix="${GettextInstallDir}" ${GettextConfigureOptions}
381
382         mkdir -p "${GettextBuildDir}" && cd "${GettextBuildDir}"
383
384         # ----------------------------------------
385         # Build Gettext for different architectures
386         # ----------------------------------------
387         FILE_LIST="${GettextLibrary}"
388
389         for arch in ${ARCH_LIST} ; do
390                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
391                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
392                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
393                 "${GettextSourceDir}/configure"\
394                         --prefix="${GettextInstallDir}"\
395                         ${GettextConfigureOptions}
396                 make && make install${strip}
397                 for file in ${FILE_LIST} ; do
398                         if [ -f "${GettextInstallDir}"/lib/${file} ]; then
399                                 mv "${GettextInstallDir}"/lib/${file}\
400                                         "${GettextInstallDir}"/lib/${file}-${arch} 
401                         else
402                                 echo Cannot build and install Gettext for ${arch}.
403                                 exit 1
404                         fi
405                 done
406         done
407         # -------------------------
408         # Create universal binaries
409         # -------------------------
410         for file in ${FILE_LIST} ; do
411                 OBJ_LIST=
412                 for arch in ${ARCH_LIST} ; do
413                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
414                 done
415                 (
416                         cd "${GettextInstallDir}"
417                         lipo -create ${OBJ_LIST} -o lib/${file}
418                 )
419         done
420         # --------
421         # Clean up
422         # --------
423         for arch in ${ARCH_LIST} ; do
424                 rm -f "${GettextInstallDir}"/lib/*-${arch}
425         done
426 fi
427
428 if [ -d "${HunSpellSourceDir}" -a ! -f "${HunSpellInstallHdr}" ]; then
429         # we have a private HunSpell source tree at hand...
430         # so let's build and install it
431         if [ -z "${HunSpellVersion}" ]; then
432                 HunSpellVersion=$(grep AC_INIT "${HunSpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
433         fi
434
435         HunSpellName="Hunspell"
436         HunSpellBase="${HunSpellName}-${HunSpellVersion}"
437
438         echo Build hunspell library ${HunSpellBase}
439         echo configure options:
440         echo --prefix="${HunSpellInstallDir}" ${HunspellConfigureOptions}
441
442         mkdir -p "${HunSpellBuildDir}" && cd "${HunSpellBuildDir}"
443
444         # ----------------------------------------
445         # Build HunSpell for different architectures
446         # ----------------------------------------
447         FILE_LIST="${HunSpellLibrary}"
448
449         for arch in ${ARCH_LIST} ; do
450                 make distclean
451                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
452                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
453                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
454                 "${HunSpellSourceDir}/configure"\
455                         --prefix="${HunSpellInstallDir}"\
456                         ${HunspellConfigureOptions}
457                 make && make install${strip}
458                 for file in ${FILE_LIST} ; do
459                         if [ -f "${HunSpellInstallDir}"/lib/${file} ]; then
460                                 mv "${HunSpellInstallDir}"/lib/${file}\
461                                         "${HunSpellInstallDir}"/lib/${file}-${arch} 
462                         else
463                                 echo Cannot build and install HunSpell for ${arch}.
464                                 exit 1
465                         fi
466                 done
467         done
468         # -------------------------
469         # Create universal binaries
470         # -------------------------
471         for file in ${FILE_LIST} ; do
472                 OBJ_LIST=
473                 for arch in ${ARCH_LIST} ; do
474                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
475                 done
476                 (
477                         cd "${HunSpellInstallDir}"
478                         lipo -create ${OBJ_LIST} -o lib/${file}
479                         # check for the "missing link"...
480                         test -f lib/libhunspell.dylib || (cd lib ; ln -s "${HunSpellLibrary}" libhunspell.dylib)
481                 )
482         done
483         # --------
484         # Clean up
485         # --------
486         for arch in ${ARCH_LIST} ; do
487                 rm -f "${HunSpellInstallDir}"/lib/*-${arch}
488         done
489 fi
490
491 if [ -d "${ASpellSourceDir}" -a ! -f "${ASpellInstallHdr}" -a "yes" = "${aspell_deployment}" ]; then
492         # we have a private ASpell source tree at hand...
493         # so let's build and install it
494         if [ -z "${ASpellVersion}" ]; then
495                 ASpellVersion=$(grep AC_INIT "${ASpellSourceDir}"/configure.ac | cut -d, -f2|tr -d " ()")
496         fi
497
498         ASpellName="Aspell"
499         ASpellBase="${ASpellName}-${ASpellVersion}"
500
501         echo Build aspell library ${ASpellBase}
502         echo configure options:
503         echo --prefix="${ASpellInstallDir}" ${AspellConfigureOptions}
504
505         # ASpell builds inplace only :(
506         cd "${ASpellSourceDir}"
507
508         # ----------------------------------------
509         # Build ASpell for different architectures
510         # ----------------------------------------
511         FILE_LIST="${ASpellLibrary}"
512
513         for arch in ${ARCH_LIST} ; do
514                 make distclean
515                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export CPPFLAGS
516                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"; export LDFLAGS
517                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
518                 CXXFLAGS=-g "${ASpellSourceDir}/configure"\
519                         --prefix="${ASpellInstallDir}"\
520                         ${AspellConfigureOptions}
521                 make && make install${aspellstrip}
522                 for file in ${FILE_LIST} ; do
523                         if [ -f "${ASpellInstallDir}"/lib/${file} ]; then
524                                 mv "${ASpellInstallDir}"/lib/${file}\
525                                         "${ASpellInstallDir}"/lib/${file}-${arch} 
526                         else
527                                 echo Cannot build and install ASpell for ${arch}.
528                                 exit 1
529                         fi
530                 done
531         done
532         # -------------------------
533         # Create universal binaries
534         # -------------------------
535         for file in ${FILE_LIST} ; do
536                 OBJ_LIST=
537                 for arch in ${ARCH_LIST} ; do
538                         OBJ_LIST="${OBJ_LIST} lib/${file}-${arch}"
539                 done
540                 (
541                         cd "${ASpellInstallDir}"
542                         lipo -create ${OBJ_LIST} -o lib/${file}
543                 )
544         done
545         # --------
546         # Clean up
547         # --------
548         for arch in ${ARCH_LIST} ; do
549                 rm -f "${ASpellInstallDir}"/lib/*-${arch}
550         done
551 fi
552
553
554 framework_name() {
555         echo "Frameworks/${1}.framework"
556 }
557
558 LYX_FILE_LIST="lyx lyxclient tex2lyx"
559 BUNDLE_PATH="Contents/MacOS"
560 LYX_BUNDLE_PATH="${LyxAppPrefix}/${BUNDLE_PATH}"
561 build_lyx() {
562         # Clear Output
563         if [ -n "${LyxAppZip}" -a -f "${LyxAppZip}" ]; then rm "${LyxAppZip}"; fi
564         if [ -d "${LyxAppPrefix}" ]; then rm -rf "${LyxAppPrefix}"; fi
565
566         # -------------------------------------
567         # Automate configure check
568         # -------------------------------------
569         if [ ! -f "${LyxSourceDir}"/configure -o "${LyxSourceDir}"/configure -ot "${LyxSourceDir}"/configure.ac ]; then
570                 ( cd "${LyxSourceDir}" && sh autogen.sh )
571         else
572                 find "${LyxSourceDir}" -name Makefile.am -print | while read file ; do
573                         dname=$(dirname "$file")
574                         if [ -f "$dname/Makefile.in" -a "$dname/Makefile.in" -ot "$file" ]; then
575                                 ( cd "${LyxSourceDir}" && sh autogen.sh )
576                                 break
577                         fi
578                 done
579         fi
580         # -------------------------------------
581         # Build LyX for different architectures
582         # -------------------------------------
583
584         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_deployment}" ]; then
585                 ConfigureExtraInc="--with-extra-inc=${ASpellInstallDir}/include"
586                 ConfigureExtraLib="--with-extra-lib=${ASpellInstallDir}/lib"
587         fi
588
589         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_deployment}" ]; then
590                 HunSpellFramework=$(framework_name Hunspell)
591                 HunSpellFramework=$(basename "${HunSpellFramework}")
592                 ConfigureExtraInc="--with-extra-inc=${HunSpellInstallDir}/include"
593                 ConfigureExtraLib="--with-extra-lib=${HunSpellInstallDir}/lib"
594                 # LyXConfigureOptions="${LyXConfigureOptions} --with-hunspell-framework=${HunSpellFramework}"
595         fi
596         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraInc}"
597         LyXConfigureOptions="${LyXConfigureOptions} ${ConfigureExtraLib}"
598
599         for arch in ${ARCH_LIST} ; do
600
601                 if [ -d "${LyxBuildDir}" ];  then rm -r "${LyxBuildDir}"; fi
602                 mkdir -p "${LyxBuildDir}" && cd "${LyxBuildDir}"
603
604                 CPPFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
605                 LDFLAGS="${SDKROOT:+-isysroot ${SDKROOT}} -arch ${arch} ${MYCFLAGS}"
606                 HOSTSYSTEM=$(eval "echo \\$HostSystem_$arch")
607
608                 if [ "$configure_qt4_frameworks" = "yes" ]; then
609                         export QT4_CORE_CFLAGS="-FQtCore"
610                         export QT4_CORE_LIBS="-framework QtCore"
611                         export QT4_FRONTEND_CFLAGS="-FQtGui"
612                         export QT4_FRONTEND_LIBS="-framework QtGui"
613                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtCore.framework/Headers"
614                         CPPFLAGS="${CPPFLAGS} -I${SDKROOT}/Library/Frameworks/QtGui.framework/Headers"
615                 fi
616
617                 echo LDFLAGS="${LDFLAGS}"
618                 export LDFLAGS
619                 echo CPPFLAGS="${CPPFLAGS}"
620                 export CPPFLAGS
621                 echo CONFIGURE_OPTIONS="${LyXConfigureOptions}" ${QtInstallDir:+"--with-qt4-dir=${QtInstallDir}"}
622                 "${LyxSourceDir}/configure"\
623                         --prefix="${LyxAppPrefix}" --with-version-suffix="-${LyXVersionSuffix}"\
624                         ${QtInstallDir:+"--with-qt4-dir=${QtInstallDir}"} \
625                         ${LyXConfigureOptions}\
626                         --enable-build-type=rel && \
627                 make ${MAKEJOBS} && make install${strip}
628                 for file in ${LYX_FILE_LIST} ; do
629                         if [ -f "${LYX_BUNDLE_PATH}/${file}" ]; then
630                                 mv "${LYX_BUNDLE_PATH}/${file}"\
631                                         "${LYX_BUNDLE_PATH}/${file}-${arch}" 
632                         else
633                                 echo ERROR: Cannot build and install LyX for ${arch}.
634                                 exit 1
635                         fi
636                 done
637         done
638 }
639
640 content_directory() {
641         target="$1"
642         content=$(dirname "${target}")
643         content=$(dirname "${content}")
644         echo "${content}"
645 }
646
647 private_framework() {
648         fwdir=$(framework_name "$1")
649         source="$2"
650         target="$3"
651         condir=$(content_directory "${target}")
652         libnm=$(basename "${source}")
653         mkdir -p "${condir}/${fwdir}"
654         if [ ! -f "${condir}/${fwdir}/${libnm}" ]; then
655                 cp -p "${source}" "${condir}/${fwdir}"
656                 echo Set library id in "${condir}/${fwdir}/${libnm}"
657                 install_name_tool -id "@executable_path/../${fwdir}/${libnm}" "${condir}/${fwdir}/${libnm}"
658         fi
659         echo Correct library id reference to "${libnm}" in "${target}"
660         install_name_tool -change "${source}" "@executable_path/../${fwdir}/${libnm}" "${target}"
661 }
662
663 deploy_qtlibs() {
664         source="${QtInstallDir}"
665         target="$1"
666         version="Versions/${QtFrameworkVersion}/"
667         condir=$(content_directory "${target}")
668         mkdir -p "${condir}/Resources"
669         test -f "${condir}/Resources/qt.conf" || cat - > "${condir}/Resources/qt.conf" <<-EOF
670 [Paths]
671 Plugins = PlugIns
672 Translations = translations
673 EOF
674         if [ ! -d "${condir}/PlugIns" ]; then
675                 mkdir -p "${condir}/PlugIns"
676                 find "${source}/plugins" -name \*.dylib -print | while read libname ; do
677                         echo Copy plugin "${libname}"
678                         dylib=$(basename "${libname}")
679                         dirname=$(dirname "${libname}")
680                         dirname=$(basename "${dirname}")
681                         mkdir -p "${condir}/PlugIns/${dirname}"
682                         cp -p "${libname}" "${condir}/PlugIns/${dirname}"
683                 done
684         fi
685         for libnm in ${QtLibraries} ; do
686                 fwdir=$(framework_name "$libnm")
687                 dirname=$(dirname "${fwdir}")
688                 mkdir -p "${condir}/${dirname}"
689                 dirname=$(basename "${fwdir}")
690                 test -d "${condir}/${fwdir}" || (
691                         echo Copy framework "${source}/lib/"$(basename "${fwdir}")
692                         cp -pR "${source}/lib/"$(basename "${fwdir}") "${condir}/${fwdir}"
693                         echo Set library id in "${condir}/${fwdir}/${version}${libnm}"
694                         install_name_tool -id "@executable_path/../${fwdir}/${version}${libnm}" "${condir}/${fwdir}/${version}${libnm}"
695                         find "${condir}/PlugIns" "${condir}/"$(dirname "${fwdir}") -name Headers -prune -o -type f -print | while read filename ; do
696                                 if [ "${filename}" != "${target}" ]; then
697                                         otool -L "${filename}" 2>/dev/null | sort -u | while read library ; do
698                                                 # pattern match for: /path/to/qt4/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.6.0, current version 4.6.2)
699                                                 case "${library}" in
700                                                 *"${libnm}"*"("*version*")"*)
701                                                         echo Correct library id reference to "${libnm}" in "${filename}"
702                                                         install_name_tool -change\
703                                                                 "${source}/lib/${dirname}/${version}${libnm}"\
704                                                                 "@executable_path/../${fwdir}/${version}${libnm}"\
705                                                                 "${filename}"
706                                                         ;;
707                                                 esac
708                                         done
709                                 fi
710                         done
711                 )
712                 echo Correct library id reference to "${libnm}" in "${target}"
713                 install_name_tool -change\
714                         "${source}/lib/${dirname}/${version}${libnm}"\
715                         "@executable_path/../${fwdir}/${version}${libnm}"\
716                         "${target}"
717         done
718         if [ ! -d "${condir}/translations" ]; then
719                 mkdir -p "${condir}/translations"
720         fi
721         echo Copy Qt translations to "${condir}/translations"
722         cp -p "${source}"/translations/qt_*.qm "${condir}/translations"
723 }
724
725 # -------------------------
726 # Create universal binaries
727 # -------------------------
728 convert_universal() {
729         cd "${LyxAppPrefix}"
730         for file in ${LYX_FILE_LIST} ; do
731                 OBJ_LIST=
732                 for arch in ${ARCH_LIST} ; do
733                         if [ -f "${BUNDLE_PATH}/${file}-${arch}" ]; then
734                                 OBJ_LIST="${OBJ_LIST} ${BUNDLE_PATH}/${file}-${arch}"
735                         fi
736                 done
737                 if [ -n "${OBJ_LIST}" ]; then
738                         lipo -create ${OBJ_LIST} -o "${BUNDLE_PATH}/${file}"
739                 fi
740                 if [ -f "${GettextInstallDir}/lib/${GettextLibrary}" -a "yes" = "${gettext_deployment}" ]; then
741                         private_framework Gettext "${GettextInstallDir}/lib/${GettextLibrary}" "${LYX_BUNDLE_PATH}/${file}"
742                 fi
743                 if [ -f "${ASpellInstallDir}/lib/${ASpellLibrary}" -a "yes" = "${aspell_deployment}" ]; then
744                         private_framework Aspell "${ASpellInstallDir}/lib/${ASpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
745                 fi
746                 if [ -f "${HunSpellInstallDir}/lib/${HunSpellLibrary}" -a "yes" = "${hunspell_deployment}" ]; then
747                         private_framework Hunspell "${HunSpellInstallDir}/lib/${HunSpellLibrary}" "${LYX_BUNDLE_PATH}/${file}"
748                 fi
749                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt4_deployment}" ]; then
750                         deploy_qtlibs "${LYX_BUNDLE_PATH}/${file}"
751                 fi
752                 otool -L "${BUNDLE_PATH}/${file}" | while read reference ; do
753                         case "${reference}" in
754                         *"${LyxBuildDir}"*"("*")")
755                                 echo ERROR: Bad reference to "${reference}" found!!
756                                 ;;
757                         esac
758                 done
759         done
760         for arch in ${ARCH_LIST} ; do
761                 rm -f ${BUNDLE_PATH}/*-${arch}
762         done
763 }
764
765 copy_dictionaries() {
766         if [ -d "${ASpellInstallDir}" -a "yes" = "${aspell_dictionaries}" ]; then
767                 ASpellResources="${LyxAppPrefix}/Contents/Resources"
768                 # try to reuse macports dictionaries for now
769                 if [ -d /opt/local/lib/aspell-0.60 ]; then ASpellInstallDir=/opt/local ; fi
770                 mkdir -p "${ASpellResources}"
771                 echo Copy Aspell dictionaries from "${ASpellInstallDir}"
772                 mkdir -p "${ASpellResources}"/data "${ASpellResources}"/dicts
773                 cp -p -r "${ASpellInstallDir}/lib/aspell-0.60"/* "${ASpellResources}"/data
774                 cp -p -r "${ASpellInstallDir}/share/aspell"/* "${ASpellResources}"/dicts
775         fi
776         if [ -d "${HunSpellInstallDir}" -a "yes" = "${hunspell_dictionaries}" ]; then
777                 HunSpellResources="${LyxAppPrefix}/Contents/Resources"
778                 if [ -d "${DictionarySourceDir}" ]; then
779                         ( cd "${DictionarySourceDir}" && find dicts -name .svn -prune -o -type f -print | cpio -pmdv "${HunSpellResources}" )
780                 fi
781         fi
782         if [ -d "${DictionarySourceDir}" -a "yes" = "${thesaurus_deployment}" ]; then
783                 MyThesResources="${LyxAppPrefix}/Contents/Resources"
784                 ( cd "${DictionarySourceDir}" && find thes -name .svn -prune -o -type f -print | cpio -pmdv "${MyThesResources}" )
785         fi
786 }
787
788 set_bundle_display_options() {
789         X_BOUNDS=$2
790         Y_BOUNDS=$3
791         Y_POSITION=$((Y_BOUNDS - 65))
792         Y_BOUNDS=$((Y_BOUNDS + 20))
793         LYX_X_POSITION=$((X_BOUNDS / 4))
794         LYX_Y_POSITION=$Y_POSITION
795         APP_X_POSITION=$((3 * X_BOUNDS / 4))
796         APP_Y_POSITION=$Y_POSITION
797         WITH_DOCUMENTS=$(test -d "${1}/Documents" && echo true || echo false)
798         osascript <<-EOF
799         tell application "Finder"
800         set f to POSIX file ("${1}" as string) as alias
801         tell folder f
802             open
803             tell container window
804                 set toolbar visible to false
805                 set statusbar visible to false
806                 set current view to icon view
807                 delay 1 -- sync
808                 set the bounds to {20, 50, $X_BOUNDS, $Y_BOUNDS}
809             end tell
810             delay 1 -- sync
811             set icon size of the icon view options of container window to 64
812             set arrangement of the icon view options of container window to not arranged
813             if ${WITH_DOCUMENTS} then
814                set position of item "Documents" to {$LYX_X_POSITION,0}
815             end if
816             set position of item "${LyxName}.app" to {$LYX_X_POSITION,$LYX_Y_POSITION}
817             set position of item "Applications" to {$APP_X_POSITION,$APP_Y_POSITION}
818             set background picture of the icon view options\
819                of container window to file "background.png" of folder "Pictures"
820             set the bounds of the container window to {0, 0, $X_BOUNDS, $Y_BOUNDS}
821             update without registering applications
822             delay 5 -- sync
823             close
824         end tell
825         delay 5 -- sync
826     end tell
827 EOF
828 }
829
830 make_dmg() {
831         cd "${1}"
832
833         BGSIZE=$(file "$DmgBackground" | awk -F , '/PNG/{print $2 }' | tr x ' ')
834         BG_W=$(echo ${BGSIZE} | awk '{print $1 }')
835         BG_H=$(echo ${BGSIZE} | awk '{print $2 }')
836
837         rm -f "${DMGNAME}.sparseimage" "${DMGNAME}.dmg"
838
839         hdiutil create -type SPARSE -size ${DMGSIZE:-"250m"} -fs HFS+ -volname "${LyxBase}" "${DMGNAME}"
840         # Unmount currently mounted disk image
841         test -d /Volumes/"${LyxBase}" && umount /Volumes/"${LyxBase}"
842
843         # Mount the disk image
844         hdiutil attach "${DMGNAME}.sparseimage"
845
846         # Obtain device information
847         DEVS=$(hdiutil attach "${DMGNAME}.sparseimage" | cut -f 1)
848         DEV=$(echo $DEVS | cut -f 1 -d ' ')
849         VOLUME=$(mount |grep ${DEV} | cut -f 3 -d ' ')
850
851         # copy in the application bundle
852         cp -Rp "${LyxAppDir}.app" "${VOLUME}/${LyxName}.app"
853
854         # copy in background image
855         mkdir -p "${VOLUME}/Pictures"
856         cp "${DmgBackground}" "${VOLUME}/Pictures/background.png"
857         # symlink applications
858         ln -s /Applications/ "${VOLUME}"/Applications
859         test -d "${DocumentationDir}" && cp -r "${DocumentationDir}" "${VOLUME}"
860         set_bundle_display_options "${VOLUME}" ${BG_W} ${BG_H}
861         ${XCODE_DEVELOPER}/Tools/SetFile -a C "${VOLUME}"
862         mv "${VOLUME}/Pictures" "${VOLUME}/.Pictures"
863
864         # Unmount the disk image
865         hdiutil detach ${DEV}
866
867         # Convert the disk image to read-only
868         hdiutil convert "${DMGNAME}.sparseimage" -format UDBZ -o "${DMGNAME}.dmg"
869         rm -f "${DMGNAME}.sparseimage"
870 }
871
872 # ------------------------------
873 # Building distribution packages
874 # ------------------------------
875
876 build_package() {
877         test -n "${LyxAppZip}" && (
878                 cd "${LyxAppPrefix}" && zip -r "${LyxAppZip}" .
879         )
880
881         test -n "${DMGLocation}" && (
882                 make_dmg "${DMGLocation}"
883                 if [ -d "${QtInstallDir}/lib/QtCore.framework/Versions/${QtFrameworkVersion}" -a "yes" = "${qt4_deployment}" ]; then
884                         rm -f "${DMGLocation}/${DMGNAME}+qt4.dmg"
885                         echo move to "${DMGLocation}/${DMGNAME}+qt4${Qt4API}.dmg"
886                         mv "${DMGLocation}/${DMGNAME}.dmg" "${DMGLocation}/${DMGNAME}+qt4${Qt4API}.dmg"
887                 fi
888         )
889 }
890
891 # ------------------------------
892 # main block
893 # ------------------------------
894
895 if [ ${LyxOnlyPackage:-"no"} = "no" ]; then
896         build_lyx
897         convert_universal
898         copy_dictionaries
899 fi
900 build_package