forked from meganz/MEGAsync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
installer_mac.sh
executable file
·365 lines (316 loc) · 14.1 KB
/
installer_mac.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
#!/bin/zsh -e
Usage () {
echo "Usage: installer_mac.sh [[--arch [arm64|x86_64]] [--build | --build-cmake] | [--sign] | [--create-dmg] | [--notarize] | [--full-pkg | --full-pkg-cmake]]"
echo " --arch [arm64|x86_64] : Arch target. It will build for the host arch if not defined."
echo " --build : Builds the app and creates the bundle using qmake."
echo " --build-cmake : Idem but using cmake"
echo " --sign : Sign the app"
echo " --create-dmg : Create the dmg package"
echo " --notarize : Notarize package against Apple systems."
echo " --full-pkg : Implies and overrides all the above using qmake"
echo " --full-pkg-cmake : Idem but using cmake"
echo ""
echo "Environment variables needed to build:"
echo " MEGAQTPATH : Point it to a valid Qt installation path"
echo " VCPKGPATH : Point it to a directory containing a valid vcpkg installation"
echo ""
echo "Note: --build and --build-cmake are mutually exclusive."
echo " --full-pkg and --full-pkg-cmake are mutually exclusive."
echo ""
}
if [ $# -eq 0 ]; then
Usage
exit 1
fi
APP_NAME=MEGAsync
ID_BUNDLE=mega.mac
MOUNTDIR=tmp
RESOURCES=installer/resourcesDMG
MSYNC_PREFIX=MEGASync/
MUPDATER_PREFIX=MEGAUpdater/
host_arch=`uname -m`
target_arch=${host_arch}
full_pkg=0
full_pkg_cmake=0
build=0
build_cmake=0
sign=0
createdmg=0
notarize=0
build_time=0
sign_time=0
dmg_time=0
notarize_time=0
total_time=0
while [ "$1" != "" ]; do
case $1 in
--arch )
shift
target_arch="${1}"
if [ "${target_arch}" != "arm64" ] && [ "${target_arch}" != "x86_64" ]; then Usage; echo "Error: Invalid arch value."; exit 1; fi
;;
--build )
build=1
if [ ${build_cmake} -eq 1 ]; then Usage; echo "Error: --build and --build-cmake are mutually exclusive."; exit 1; fi
;;
--build-cmake )
build_cmake=1
if [ ${build} -eq 1 ]; then Usage; echo "Error: --build and --build-cmake are mutually exclusive."; exit 1; fi
;;
--sign )
sign=1
;;
--create-dmg )
createdmg=1
;;
--notarize )
notarize=1
;;
--full-pkg )
if [ ${full_pkg_cmake} -eq 1 ]; then Usage; echo "Error: --full-pkg and --full-pkg-cmake are mutually exclusive."; exit 1; fi
full_pkg=1
;;
--full-pkg-cmake )
if [ ${full_pkg} -eq 1 ]; then Usage; echo "Error: --full-pkg and --full-pkg-cmake are mutually exclusive."; exit 1; fi
full_pkg_cmake=1
;;
-h | --help )
Usage
exit
;;
* )
Usage
echo "Unknown parameter: ${1}"
exit 1
esac
shift
done
if [ ${full_pkg} -eq 1 ]; then
build=1
build_cmake=0
sign=1
createdmg=1
notarize=1
fi
if [ ${full_pkg_cmake} -eq 1 ]; then
build=0
build_cmake=1
sign=1
createdmg=1
notarize=1
fi
if [ ${build} -ne 1 -a ${build_cmake} -ne 1 -a ${sign} -ne 1 -a ${createdmg} -ne 1 -a ${notarize} -ne 1 ]; then
Usage
echo "Error: No action selected. Nothing to do."
exit 1
fi
if [ ${build} -eq 1 -o ${build_cmake} -eq 1 ]; then
build_time_start=`date +%s`
if [ -z "${MEGAQTPATH}" ] || [ ! -d "${MEGAQTPATH}/bin" ]; then
echo "Please set MEGAQTPATH env variable to a valid QT installation path!"
exit 1;
fi
if [ -z "${VCPKGPATH}" ] || [ ! -d "${VCPKGPATH}/vcpkg/installed" ]; then
echo "Please set VCPKGPATH env variable to a directory containing a valid vcpkg installation!"
exit 1;
fi
MEGAQTPATH="$(cd "$MEGAQTPATH" && pwd -P)"
echo "Building with:"
echo " MEGAQTPATH : ${MEGAQTPATH}"
echo " VCPKGPATH : ${VCPKGPATH}"
if ! lipo -archs ${MEGAQTPATH}/lib/QtCore.framework/QtCore 2>/dev/null | grep ${target_arch} >/dev/null; then
echo "Qt libs for ${target_arch} are not present in ${MEGAQTPATH} Qt installation."
exit 1
fi
if [ ${build_cmake} -ne 1 ]; then
AVCODEC_VERSION=libavcodec.58.dylib
AVFORMAT_VERSION=libavformat.58.dylib
AVUTIL_VERSION=libavutil.56.dylib
SWSCALE_VERSION=libswscale.5.dylib
CARES_VERSION=libcares.2.dylib
CURL_VERSION=libcurl.dylib
AVCODEC_PATH=${VCPKGPATH}/vcpkg/installed/${target_arch//x86_64/x64}-osx-mega/lib/$AVCODEC_VERSION
AVFORMAT_PATH=${VCPKGPATH}/vcpkg/installed/${target_arch//x86_64/x64}-osx-mega/lib/$AVFORMAT_VERSION
AVUTIL_PATH=${VCPKGPATH}/vcpkg/installed/${target_arch//x86_64/x64}-osx-mega/lib/$AVUTIL_VERSION
SWSCALE_PATH=${VCPKGPATH}/vcpkg/installed/${target_arch//x86_64/x64}-osx-mega/lib/$SWSCALE_VERSION
CARES_PATH=${VCPKGPATH}/vcpkg/installed/${target_arch//x86_64/x64}-osx-mega/lib/$CARES_VERSION
CURL_PATH=${VCPKGPATH}/vcpkg/installed/${target_arch//x86_64/x64}-osx-mega/lib/$CURL_VERSION
fi
# Clean previous build
rm -rf Release_${target_arch}
mkdir Release_${target_arch}
cd Release_${target_arch}
# Build binaries
if [ ${build_cmake} -eq 1 ]; then
# Detect crosscompilation and set CMAKE_OSX_ARCHITECTURES.
if [ "${target_arch}" != "${host_arch}" ]; then
CMAKE_EXTRA="-DCMAKE_OSX_ARCHITECTURES=${target_arch}"
fi
cmake -DUSE_THIRDPARTY_FROM_VCPKG=1 -DMega3rdPartyDir=${VCPKGPATH} -DCMAKE_PREFIX_PATH=${MEGAQTPATH} -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_EXTRA} -S ../contrib/cmake
cmake --build ./ --target MEGAsync -j`sysctl -n hw.ncpu`
cmake --build ./ --target MEGAupdater -j`sysctl -n hw.ncpu`
MSYNC_PREFIX=""
MUPDATER_PREFIX=""
else
# crosscompilation detection should be managed detecting the qmake taget and host arch in the project files.
cp ../src/MEGASync/mega/contrib/official_build_configs/macos/config.h ../src/MEGASync/mega/include/mega/config.h
${MEGAQTPATH}/bin/lrelease ../src/MEGASync/MEGASync.pro
${MEGAQTPATH}/bin/qmake "CONFIG += FULLREQUIREMENTS" "THIRDPARTY_VCPKG_BASE_PATH=${VCPKGPATH}" -r ../src -spec macx-clang CONFIG+=release -nocache
make -j`sysctl -n hw.ncpu`
fi
# Prepare bundle
cp -R ${MSYNC_PREFIX}MEGAsync.app ${MSYNC_PREFIX}MEGAsync_orig.app
${MEGAQTPATH}/bin/macdeployqt ${MSYNC_PREFIX}MEGAsync.app -no-strip
dsymutil ${MSYNC_PREFIX}MEGAsync.app/Contents/MacOS/MEGAsync -o MEGAsync.app.dSYM
strip ${MSYNC_PREFIX}MEGAsync.app/Contents/MacOS/MEGAsync
dsymutil ${MUPDATER_PREFIX}MEGAupdater.app/Contents/MacOS/MEGAupdater -o MEGAupdater.dSYM
strip ${MUPDATER_PREFIX}MEGAupdater.app/Contents/MacOS/MEGAupdater
mv ${MUPDATER_PREFIX}MEGAupdater.app/Contents/MacOS/MEGAupdater ${MSYNC_PREFIX}MEGAsync.app/Contents/MacOS/MEGAupdater
touch ${MSYNC_PREFIX}MEGAsync.app/Contents/MacOS/MEGAclient
if [ ${build_cmake} -ne 1 ]; then
[ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$AVCODEC_VERSION ] && cp -L $AVCODEC_PATH MEGASync/MEGAsync.app/Contents/Frameworks/
[ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$AVFORMAT_VERSION ] && cp -L $AVFORMAT_PATH MEGASync/MEGAsync.app/Contents/Frameworks/
[ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$AVUTIL_VERSION ] && cp -L $AVUTIL_PATH MEGASync/MEGAsync.app/Contents/Frameworks/
[ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$SWSCALE_VERSION ] && cp -L $SWSCALE_PATH MEGASync/MEGAsync.app/Contents/Frameworks/
[ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$CARES_VERSION ] && cp -L $CARES_PATH MEGASync/MEGAsync.app/Contents/Frameworks/
[ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$CURL_VERSION ] && cp -L $CURL_PATH MEGASync/MEGAsync.app/Contents/Frameworks/
if [ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$AVCODEC_VERSION ] \
|| [ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$AVFORMAT_VERSION ] \
|| [ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$AVUTIL_VERSION ] \
|| [ ! -f MEGASync/MEGAsync.app/Contents/Frameworks/$SWSCALE_VERSION ];
then
echo "Error copying FFmpeg libs to app bundle."
exit 1
fi
fi
MEGASYNC_VERSION=`grep "const QString Preferences::VERSION_STRING" ../src/MEGASync/control/Preferences.cpp | awk -F '"' '{print $2}'`
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $MEGASYNC_VERSION" "${MSYNC_PREFIX}$APP_NAME.app/Contents/Info.plist"
if [ ${build_cmake} -ne 1 ]; then
install_name_tool -change @loader_path/$AVCODEC_VERSION @executable_path/../Frameworks/$AVCODEC_VERSION MEGASync/MEGAsync.app/Contents/MacOS/MEGAsync
install_name_tool -change @loader_path/$AVFORMAT_VERSION @executable_path/../Frameworks/$AVFORMAT_VERSION MEGASync/MEGAsync.app/Contents/MacOS/MEGAsync
install_name_tool -change @loader_path/$AVUTIL_VERSION @executable_path/../Frameworks/$AVUTIL_VERSION MEGASync/MEGAsync.app/Contents/MacOS/MEGAsync
install_name_tool -change @loader_path/$SWSCALE_VERSION @executable_path/../Frameworks/$SWSCALE_VERSION MEGASync/MEGAsync.app/Contents/MacOS/MEGAsync
rm -r $APP_NAME.app || :
mv $MSYNC_PREFIX/$APP_NAME.app ./
fi
otool -L MEGAsync.app/Contents/MacOS/MEGAsync
#Attach shell extension
xcodebuild clean build CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO -jobs "$(sysctl -n hw.ncpu)" -configuration Release -target MEGAShellExtFinder -project ../src/MEGAShellExtFinder/MEGAFinderSync.xcodeproj/
cp -a ../src/MEGAShellExtFinder/build/Release/MEGAShellExtFinder.appex $APP_NAME.app/Contents/Plugins/
cd ..
build_time=`expr $(date +%s) - $build_time_start`
fi
if [ "$sign" = "1" ]; then
sign_time_start=`date +%s`
cd Release_${target_arch}
cp -R $APP_NAME.app ${APP_NAME}_unsigned.app
echo "Signing 'APPBUNDLE'"
codesign --force --verify --verbose --preserve-metadata=entitlements --options runtime --sign "Developer ID Application: Mega Limited" --deep $APP_NAME.app
echo "Checking signature"
spctl -vv -a $APP_NAME.app
cd ..
sign_time=`expr $(date +%s) - $sign_time_start`
fi
if [ "$createdmg" = "1" ]; then
dmg_time_start=`date +%s`
cd Release_${target_arch}
[ -f $APP_NAME.dmg ] && rm $APP_NAME.dmg
echo "DMG CREATION PROCESS..."
echo "Creating temporary Disk Image (1/7)"
#Create a temporary Disk Image
/usr/bin/hdiutil create -srcfolder $APP_NAME.app/ -volname $APP_NAME -ov $APP_NAME-tmp.dmg -fs HFS+ -format UDRW >/dev/null
echo "Attaching the temporary image (2/7)"
#Attach the temporary image
mkdir $MOUNTDIR
/usr/bin/hdiutil attach $APP_NAME-tmp.dmg -mountroot $MOUNTDIR >/dev/null
echo "Copying resources (3/7)"
#Copy the background, the volume icon and DS_Store files
unzip -d $MOUNTDIR/$APP_NAME ../$RESOURCES.zip
/usr/bin/SetFile -a C $MOUNTDIR/$APP_NAME
echo "Adding symlinks (4/7)"
#Add a symbolic link to the Applications directory
ln -s /Applications/ $MOUNTDIR/$APP_NAME/Applications
echo "Detaching temporary Disk Image (5/7)"
#Detach the temporary image
/usr/bin/hdiutil detach $MOUNTDIR/$APP_NAME >/dev/null
echo "Compressing Image (6/7)"
#Compress it to a new image
/usr/bin/hdiutil convert $APP_NAME-tmp.dmg -format UDZO -o $APP_NAME.dmg >/dev/null
echo "Deleting temporary image (7/7)"
#Delete the temporary image
rm $APP_NAME-tmp.dmg
rmdir $MOUNTDIR
cd ..
dmg_time=`expr $(date +%s) - $dmg_time_start`
fi
if [ "$notarize" = "1" ]; then
notarize_time_start=`date +%s`
cd Release_${target_arch}
if [ ! -f $APP_NAME.dmg ];then
echo ""
echo "There is no dmg to be notarized."
echo ""
exit 1
fi
rm querystatus.txt staple.txt || :
echo "NOTARIZATION PROCESS..."
echo "Getting USERNAME for notarization commands (1/7)"
AC_USERNAME=$(security find-generic-password -s AC_PASSWORD | grep acct | cut -d '"' -f 4)
if [[ -z "$AC_USERNAME" ]]; then
echo "Error USERNAME not found for notarization process. You should add item named AC_PASSWORD with and account value matching the username to macOS keychain"
false
fi
echo "Sending dmg for notarization (2/7)"
xcrun altool --notarize-app -t osx -f $APP_NAME.dmg --primary-bundle-id $ID_BUNDLE -u $AC_USERNAME -p "@keychain:AC_PASSWORD" --output-format xml 2>&1 > staple.txt
RUUID=$(cat staple.txt | grep RequestUUID -A 1 | tail -n 1 | awk -F "[<>]" '{print $3}')
echo $RUUID
if [ ! -z "$RUUID" ] ; then
echo "Received UUID for notarization request. Checking state... (3/7)"
attempts=60
while [ $attempts -gt 0 ]
do
echo "Querying state of notarization..."
xcrun altool --notarization-info $RUUID -u $AC_USERNAME -p "@keychain:AC_PASSWORD" --output-format xml 2>&1 > querystatus.txt
RUUIDQUERY=$(cat querystatus.txt | grep RequestUUID -A 1 | tail -n 1 | awk -F "[<>]" '{print $3}')
if [[ "$RUUID" != "$RUUIDQUERY" ]]; then
echo "UUIDs missmatch"
false
fi
STATUS=$(cat querystatus.txt | grep -i ">Status<" -A 1 | tail -n 1 | awk -F "[<>]" '{print $3}')
if [[ $STATUS == "invalid" ]]; then
echo "INVALID status. Check file querystatus.txt for further information"
echo $STATUS
break
elif [[ $STATUS == "success" ]]; then
echo "Notarized ok. Stapling dmg file..."
xcrun stapler staple -v $APP_NAME.dmg
echo "Stapling ok"
#Mount dmg volume to check if app bundle is notarized
echo "Checking signature and notarization"
mkdir $MOUNTDIR || :
hdiutil attach $APP_NAME.dmg -mountroot $MOUNTDIR >/dev/null
spctl -v -a $MOUNTDIR/$APP_NAME/$APP_NAME.app
hdiutil detach $MOUNTDIR/$APP_NAME >/dev/null
rmdir $MOUNTDIR
break
else
echo $STATUS
fi
attempts=$((attempts - 1))
sleep 30
done
if [[ $attempts -eq 0 ]]; then
echo "Notarization still in process, timed out waiting for the process to end"
false
fi
fi
cd ..
notarize_time=`expr $(date +%s) - $notarize_time_start`
fi
echo ""
if [ ${build} -eq 1 -o ${build_cmake} -eq 1 ]; then echo "Build: ${build_time} s"; fi
if [ ${sign} -eq 1 ]; then echo "Sign: ${sign_time} s"; fi
if [ ${createdmg} -eq 1 ]; then echo "dmg: ${dmg_time} s"; fi
if [ ${notarize} -eq 1 ]; then echo "Notarization: ${notarize_time} s"; fi
echo ""
echo "DONE in "`expr ${build_time} + ${sign_time} + ${dmg_time} + ${notarize_time}`" s"