source: orange/install-scripts/mac/build-create-app-template.sh @ 11595:962076656c21

Revision 11595:962076656c21, 7.7 KB checked in by Ales Erjavec <ales.erjavec@…>, 11 months ago (diff)

Added a build script for an OSX application (.app) template.

Line 
1#!/bin/bash -e
2# Create (build) an Orange application bundle template
3#
4# example usage:
5#
6#   $./build-create-app-template.sh $HOME/Orange.app
7#
8
9
10SCRIPT_DIR_NAME=$(dirname "$0")
11
12BUNDLE_LITE=$SCRIPT_DIR_NAME/bundle-lite/Orange.app
13
14APP=$1
15
16if [[ ! $APP ]]; then
17    echo "Applicatition path must be specified"
18    echo "Usage: ./build-create-app-template.sh ApplicationTemplate"
19    exit 1
20fi
21
22
23PYTHON=$APP/Contents/MacOS/python
24EASY_INSTALL=$APP/Contents/MacOS/easy_install
25PIP=$APP/Contents/MacOS/pip
26
27export MACOSX_DEPLOYMENT_TARGET=10.5
28
29SDK=/Developer/SDKs/MacOSX$MACOSX_DEPLOYMENT_TARGET.sdk
30
31function create_template {
32    # Create a minimal .app template with the expected dir structure
33    # Info.plist and icons.
34
35    mkdir -p "$APP"
36    mkdir -p "$APP"/Contents/MacOS
37    mkdir -p "$APP"/Contents/Resources
38
39    # Copy icons and Info.plist
40    cp "$BUNDLE_LITE"/Contents/Resources/* "$APP"/Contents/Resources
41    cp "$BUNDLE_LITE"/Contents/Info.plist "$APP"/Contents/Info.plist
42
43    #cp $BUNDLE_LITE/Contents/PkgInfo $APP/Contents/PkgInfo
44
45    cat <<-'EOF' > "$APP"/Contents/MacOS/ENV
46    # Create an environment for running python from the bundle
47    # Should be run as "source ENV"
48
49    BUNDLE_DIR=`dirname "$0"`/../
50    BUNDLE_DIR=`perl -MCwd=realpath -e 'print realpath($ARGV[0])' "$BUNDLE_DIR"`/
51    FRAMEWORKS_DIR="$BUNDLE_DIR"Frameworks/
52    RESOURCES_DIR="$BUNDLE_DIR"Resources/
53
54    PYVERSION="2.7"
55
56    PYTHONEXECUTABLE="$FRAMEWORKS_DIR"Python.framework/Resources/Python.app/Contents/MacOS/Python
57    PYTHONHOME="$FRAMEWORKS_DIR"Python.framework/Versions/"$PYVERSION"/
58
59    DYLD_FRAMEWORK_PATH="$FRAMEWORKS_DIR"${DYLD_FRAMEWORK_PATH:+:$DYLD_FRAMEWORK_PATH}
60
61    export PYTHONEXECUTABLE
62    export PYTHONHOME
63
64    export DYLD_FRAMEWORK_PATH
65
66    # Some non framework libraries are put in $FRAMEWORKS_DIR by machlib standalone
67    export DYLD_LIBRARY_PATH="$FRAMEWORKS_DIR"${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}
68EOF
69
70}
71
72function install_python() {
73    download_and_extract http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tgz
74
75    cd Python-2.7.5
76
77    # _hashlib import fails with  Symbol not found: _EVP_MD_CTX_md
78    # The 10.5 sdk's libssl does not define it (even though it is v 0.9.7)
79    patch setup.py -i - <<-'EOF'
80        834c834
81        <         min_openssl_ver = 0x00907000
82        ---
83        >         min_openssl_ver = 0x00908000
84EOF
85
86    ./configure --enable-framework="$APP"/Contents/Frameworks \
87                --prefix="$APP"/Contents/Resources \
88                --with-universal-archs=intel \
89                --enable-universalsdk="$SDK"
90
91    make
92    make install
93    cd ..
94
95    # PythonAppStart will be used for starting the application GUI.
96    # This needs to be symlinked here for Desktop services used the app's
97    # Info.plist and not the contained Python.app's
98    ln -fs ../Frameworks/Python.framework/Resources/Python.app/Contents/MacOS/Python "$APP"/Contents/MacOS/PythonAppStart
99    ln -fs ../Frameworks/Python.framework/Resources/Python.app "$APP"/Contents/Resources/Python.app
100
101    cat <<-'EOF' > "$APP"/Contents/MacOS/python
102        #!/bin/bash
103
104        DIRNAME=$(dirname "$0")
105
106        # Set the proper env variables
107        source "$DIRNAME"/ENV
108
109        exec -a "$0" "$PYTHONEXECUTABLE" "$@"
110EOF
111
112    chmod +x "$APP"/Contents/MacOS/python
113
114    $PYTHON -c"import sys"
115
116}
117
118function install_pip() {
119    download_and_extract "https://pypi.python.org/packages/source/p/pip/pip-1.3.1.tar.gz"
120    cd pip-1.3.1
121
122    $PYTHON setup.py install
123    create_shell_start_script pip
124
125    $PIP --version
126}
127
128function install_distribute() {
129    download_and_extract "https://pypi.python.org/packages/source/d/distribute/distribute-0.6.45.tar.gz"
130    cd distribute-0.6.45
131
132    $PYTHON setup.py install
133    create_shell_start_script easy_install
134
135    $EASY_INSTALL --version
136}
137
138function install_ipython {
139    # install with easy_install (does not work with pip)
140    $EASY_INSTALL ipython
141    create_shell_start_script ipython
142}
143
144function install_qt4 {
145    download_and_extract "http://download.qt-project.org/archive/qt/4.7/qt-everywhere-opensource-src-4.7.4.tar.gz"
146    cd qt-everywhere-opensource-src-4.7.4
147
148    yes yes | ./configure -prefix "$APP"/Contents/Resources/Qt4 \
149                -libdir "$APP"/Contents/Frameworks \
150                -framework \
151                -release \
152                -opensource \
153                -no-qt3support \
154                -arch x86 -arch x86_64 \
155                -no-sql-psql \
156                -no-sql-ibase \
157                -no-sql-mysql \
158                -no-sql-odbc \
159                -no-sql-sqlite \
160                -no-sql-sqlite2 \
161                -nomake examples \
162                -nomake demos \
163                -nomake docs \
164                -nomake translations \
165                -sdk "$SDK"
166
167    make -j 4
168    make install
169
170    # Register plugins.
171    cat <<-EOF > "$APP"/Contents/Resources/qt.conf
172        [Paths]
173        Plugins = Resources/Qt4/plugins
174EOF
175
176    # In case the Python executable is invokes directly we also want it to
177    # find the plugins.
178    cat <<-EOF > "$APP"/Contents/Frameworks/Python.framework/Resources/Python.app/Contents/Resources/qt.conf
179        [Paths]
180        Plugins = ../../../../../Resources/Qt4/plugins
181EOF
182
183}
184
185function install_sip {
186    download_and_extract "http://sourceforge.net/projects/pyqt/files/sip/sip-4.14.6/sip-4.14.6.tar.gz"
187    cd sip-4.14.6
188
189    $PYTHON configure.py  --arch i386 --arch x86_64 --sdk "$SDK"
190
191    make
192    make install
193
194    $PYTHON -c"import sip"
195
196}
197
198function install_pyqt4 {
199    download_and_extract "http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.10.1/PyQt-mac-gpl-4.10.1.tar.gz"
200    cd PyQt-mac-gpl-4.10.1
201
202    yes yes | $PYTHON configure.py --qmake "$APP"/Contents/Resources/Qt4/bin/qmake
203
204    make
205    make install
206
207    $PYTHON -c"import PyQt4.QtGui, PyQt4.QtGui"
208
209}
210
211function install_pyqwt5 {
212    download_and_extract "http://sourceforge.net/projects/pyqwt/files/pyqwt5/PyQwt-5.2.0/PyQwt-5.2.0.tar.gz"
213
214    # configure.py fails (with ld: library not found for -lcrt1.10.5.o) trying to
215    # build static libraries
216    export CPPFLAGS="--shared"
217
218    cd PyQwt-5.2.0/configure
219
220    $PYTHON configure.py -Q ../qwt-5.2 \
221                        --extra-cflags="-arch i386 -arch x86_64" \
222                        --extra-cxxflags="-arch i386 -arch x86_64" \
223                        --extra-lflags="-arch i386 -arch x86_64"
224    make
225    make install
226
227    unset CPPFLAGS
228
229    $PYTHON -c"import PyQt4.Qwt5"
230}
231
232function install_numpy {
233    $PIP install numpy
234
235    $PYTHON -c"import numpy"
236}
237
238function install_scipy {
239    # This is tricky (req gfortran)
240    $PIP install scipy
241
242    $PYTHON -c"import scipy"
243}
244
245function download_and_extract() {
246    # Usage: download_and_extract http://example/source.tar.gz
247    #
248    # Download the specified .tar source package and extract it in the current dir
249    # If the source package is already present only extract it
250
251    URL=$1
252    if [[ ! $URL ]]; then
253        echo "An url expected"
254        exit 1
255    fi
256
257    SOURCE_TAR=$(basename "$URL")
258
259    if [[ ! -e $SOURCE_TAR ]]; then
260        echo "Downloading $SOURCE_TAR"
261        curl --fail -L --max-redirs 3 $URL -o $SOURCE_TAR
262    fi
263    tar -xzf $SOURCE_TAR
264}
265
266
267function create_shell_start_script() {
268    # Usage: create_shell_start_script pip
269    #
270    # create a start script for the specified script in $APP/Contents/MacOS
271
272    SCRIPT=$1
273
274    cat <<-'EOF' > "$APP"/Contents/MacOS/"$SCRIPT"
275        #!/bin/bash
276
277        DIRNAME=$(dirname "$0")
278        NAME=$(basename "$0")
279
280        # Set the proper env variables
281        source "$DIRNAME"/ENV
282
283        exec -a "$0" "$DIRNAME"/python "$FRAMEWORKS_DIR"/Python.framework/Versions/Current/bin/"$NAME" "$@"
284EOF
285
286    chmod +x "$APP"/Contents/MacOS/"$SCRIPT"
287}
288
289function cleanup {
290    # Cleanup the application bundle by removing unnecesary files.
291    find "$APP"/Contents/ \( -name '*~' -or -name '*.bak' -or -name '*.pyc' -or -name '*.pyo' -or -name '*.pyd' \) -exec rm -rf {} ';'
292
293    find "$APP"/Contents/Frameworks/*Qt*.framework -name '*_debug*' -delete
294    find "$APP"/Contents/Frameworks/*Qt*.framework -name '*_debug*' -delete
295
296    find "$APP"/Contents/Frameworks/*Qt*.framework -name '*.la' -delete
297    find "$APP"/Contents/Frameworks/*Qt*.framework -name '*.a' -delete
298    find "$APP"/Contents/Frameworks/*Qt*.framework -name '*.prl' -delete
299
300}
301
302function make_standalone {
303    $PIP install macholib
304    $PYTHON -m macholib standalone $APP
305    yes y | $PIP uninstall altgraph
306    yes y | $PIP uninstall macholib
307}
308
309create_template
310
311install_python
312
313install_distribute
314
315install_pip
316
317install_numpy
318
319install_scipy
320
321install_qt4
322
323install_sip
324
325install_pyqt4
326
327install_pyqwt5
328
329install_ipython
330
331cleanup
332
333make_standalone
Note: See TracBrowser for help on using the repository browser.