青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,長修遠,我們不能沒有錢
隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
數據加載中……

Qt for Mac DeveloperId 打包 簽名 公證 蓋章


以下腳本根據QCreator for mac工程的輸出二進制文件 進行打包 部署 簽名 上傳公證 簽章
可在工程目錄下新建一個 deployed目錄, 并將腳本拷貝到該目錄下執行, 執行需要root權限
支持cmake工程或qmake工程

此腳本不含編譯部分, 需要自行編譯, 編譯成功后方可成功執行
cd $projectDir && mkdir deployed 
cd deployed
sudo ./notarization.sh [MinSizeRel | debug | release]

腳本需要兩個證書, 分別是Developer ID Application , 對代碼進行簽名; Developer ID Installer 對pkg安裝包進行簽名, 這兩個證書只有App開發者賬戶持有者才有權限生成. 
腳本依賴工程中的一個 info.h, 該文件描述程序版本, 內容如下: 
1 #ifndef INFO_H
2 #define INFO_H
3 
4 #define VERSION "0.10.4"
5 
6 #endif // INFO_H
7 


  1 #!/bin/bash
  2 
  3 ###########################################################################
  4     QDeployd="/Users/khan/Develop/Qt/5.15.2/clang_64/bin/macdeployqt"
  5     BUNLDE_ID="com.cc.dd.app"              # bundle id
  6     USER="aa@bb.com".                           # apple開發者賬戶
  7     PASSWORD="eeee-ffff-gggg-hhhh"     # apple開發者專屬密碼(specific password) 見: https://support.apple.com/zh-cn/HT204397
  8     CERTIFICATE="Developer ID Application:iiii(team id)"
  9     INSTALLER_CERTIFICATE="Developer ID Installer: iiii (team id)"
 10 ###########################################################################
 11 
 12 ###########################################################################
 13     COLOR_NORMAL="\033[0m"
 14     COLOR_BLACK="\033[1;30m"
 15     COLOR_RED="\033[1;31m"
 16     COLOR_GREEN="\033[1;32m"
 17     COLOR_YELLOW="\033[1;33m"
 18     COLOR_BLUE="\033[1;34m"
 19     COLOR_PURPLE="\033[1;35m"
 20     COLOR_WHITE="\033[1;37m"
 21 
 22     CMAKE="1"
 23     projectName=""
 24     targetPaths=""
 25     appVersion="0.0.0"
 26 
 27     FindRet=$(find ../ -iname "info.h")
 28     if [ -n "$FindRet" ] ; then
 29         appVersion=$(cat $FindRet |grep -i 'VERSION' |sed 's|.*\"\([0-9\.]*\)\".*|\1|g')
 30     fi;
 31 
 32 
 33     if [ -f "../CMakeLists.txt" ] ; then
 34         CMAKE="1"
 35         echo -e "$COLOR_PURPLE[CMake project]$COLOR_NORMAL"
 36     else
 37         CMAKE="0"
 38         echo -e "$COLOR_PURPLE[QMake project]$COLOR_NORMAL"
 39     fi;
 40 
 41 
 42 
 43     if [ "$CMAKE" -eq "1" ] ; then
 44         projectName=$(cat ../CMakeLists.txt |grep -i 'Project(' | sed 's|.*(\([a-zA-Z0-9]*\)\ .*|\1|g')
 45     else 
 46         projectName=$(ls ../*.pro)
 47         projectName=$(echo "$projectName" | sed 's|../||g' | sed 's|.pro||g' )
 48     fi; 
 49 
 50     echo -e "Project Name $COLOR_PURPLE[$projectName V $appVersion]$COLOR_NORMAL"
 51 
 52     printHelp() {
 53         echo -e "USAGE: $0 $COLOR_YELLOW[target]$COLOR_NORMAL"
 54         echo -e "  target: $COLOR_YELLOW[debug|release]$COLOR_NORMAL"
 55         echo -e "  example: $0 $COLOR_YELLOW release $COLOR_NORMAL"
 56     }
 57 
 58     # echo -e "$#"
 59     if [ "$#" -ne "1" ] ; then
 60         printHelp
 61         exit 1
 62     fi;
 63 
 64     target=$1
 65 
 66     if [ "$CMAKE" -eq "1" ] ; then
 67         data="$(cat ../CMakeLists.txt.user)"
 68         count=$(xmllint --xpath 'count(//data/valuemap/valuemap/value[@key="ProjectExplorer.BuildConfiguration.BuildDirectory"])' - <<< "$data")
 69         for((index=1$index<=$countindex++)) ; do
 70             tmp=$(xmllint --xpath "(//data/valuemap/valuemap/value[@key='ProjectExplorer.BuildConfiguration.BuildDirectory'])[$index]/text()" - <<< "$data")
 71             targetPaths="$targetPaths$tmp\n"
 72         done
 73     else 
 74         data="$(cat ../$projectName.pro.user)"
 75         count=$(xmllint --xpath 'count(//data/valuemap/valuemap/value[@key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir"])' - <<< "$data")
 76         for((index=1$index<=$countindex++)) ; do
 77             tmp=$(xmllint --xpath "(//data/valuemap/valuemap/value[@key='ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir'])[$index]/text()" - <<< "$data")
 78             targetPaths="$targetPaths$tmp\n"
 79         done
 80     fi;
 81 
 82 
 83     targetPath=$(echo -e "$targetPaths" |grep -E -i "$target" | head -n 1)
 84     if [ -z "$targetPath" ] ; then
 85         echo -e "$projectName target$COLOR_RED dir [$target] not found$COLOR_NORMAL"
 86         exit 2
 87     fi
 88 
 89     echo -e "Deployd $COLOR_PURPLE$targetPath$COLOR_NORMAL package"
 90 ###########################################################################
 91 
 92 ###########################################################################
 93     DST_NAME=${projectName}_V${appVersion}.pkg
 94     if [ -f $DST_NAME ] ; then
 95         rm -rf $DST_NAME
 96     fi 
 97 
 98     rm -rf ./$projectName.app
 99     cp -R $targetPath/$projectName.app ./
100 
101 
102     $QDeployd $projectName.app -appstore-compliant -always-overwrite -qmldir=../Resource
103 
104     find $projectName.app -name '*.dSYM'|xargs rm -rf
105 
106     # 對qt模塊進行簽名
107     FrameworksName=$(ls $projectName.app/Contents/Frameworks/ | cut -d '.' -f 1)
108     for Item in ${FrameworksName[@]}
109     do
110         codesign --force --timestamp --entitlements Entitlements.plist --sign "$CERTIFICATE" $projectName.app/Contents/Frameworks/$Item.framework/$Item
111     done
112 
113     # 對插件進行簽名
114     DylibName=$(find $projectName.app/Contents/PlugIns/ -name *.dylib)
115     for Item in ${DylibName[@]}
116     do
117         codesign --force --timestamp --entitlements Entitlements.plist --sign "$CERTIFICATE" $Item
118     done
119 
120     codesign --sign "$CERTIFICATE" --verbose=4 --timestamp -o runtime --entitlements Entitlements.plist $projectName.app
121 
122     echo -e ""
123     codesign -dvvv $projectName.app
124     echo -e "$COLOR_PURPLE End codesign $COLOR_NORMAL\n\n"
125 ###########################################################################
126 
127 ###########################################################################
128     pkgbuild --component ${projectName}.app --install-location /Applications --sign "${INSTALLER_CERTIFICATE}" --identifier "${BUNLDE_ID}" --version ${appVersion} ${DST_NAME}
129     echo -e ""
130     pkgutil --check-signature ${DST_NAME}
131     echo -e ""
132 
133 
134     # get TEAM_ID
135     data=$(xcrun altool --list-providers -u "$USER" -p "$PASSWORD" --output-format xml)
136     TEAM_ID=$(xmllint --xpath "//dict/array/dict[key='ProviderShortname']/key[text()='ProviderShortname']/following-sibling::*[1]/text()" - <<< "$data")
137     if [ "$TEAM_ID" ]; then
138         # notarization
139         echo -e "$COLOR_PURPLE[TEAM ID: $TEAM_ID]$COLOR_NORMAL"
140         RESULT=$(xcrun altool --notarize-app --primary-bundle-id "$BUNLDE_ID" --username "$USER" --password "$PASSWORD" --asc-provider "$TEAM_ID" -t macos --file ${DST_NAME})
141         FILTER_RESULT=$(echo -e "$RESULT" | grep RequestUUID)
142         if [ "$FILTER_RESULT" ] ; then
143             RequestUUID=$(echo -e "$RESULT" |grep RequestUUID | awk '{print $3}')
144             echo -e "$projectName $COLOR_PURPLE[RequestUUID: $RequestUUID]$COLOR_NORMAL"
145 
146             sleep 150
147             xcrun altool --notarization-info "$RequestUUID" --username "$USER" --password "$PASSWORD"
148 
149             xcrun stapler staple ${DST_NAME}
150         else
151             echo -e "$projectName $COLOR_RED upload ERROR:$COLOR_NORMAL \n $RESULT"
152         fi
153     fi
154 # ###########################################################################
155 
156 echo 'Done.'
157 
158 exit
159 

簽名時需要提供權限描述, 見 Entitlements.plist, 權限描述見: https://developer.apple.com/documentation/security/app_sandbox, 可自行根據程序的功能進行增減
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 <plist version="1.0">
 4     <dict>
 5         <key>com.apple.security.app-sandbox</key>
 6         <true/>
 7         <key>com.apple.security.network.client</key>
 8         <true/>
 9         <key>com.apple.security.device.usb</key>
10         <true/>
11         <key>com.apple.security.files.user-selected.read-write</key>
12         <true/>
13         <key>com.apple.security.files.downloads.read-write</key>
14         <true/>
15     </dict>
16 </plist>
17 

腳本主要邏輯是 
- 判斷工程文件類型是qmake 還是cmake
- 根據工程文件 和 腳本參數 確認當前要處理的待處理程序在哪個目錄 [release | debug | MinSizeRel]
- 獲取當前待處理程序的版本號
- 使用application證書對framework PlugIns 進行簽名; 使用application證書對app目錄進行簽名
- 制作pkg安裝包, 并使用installer證書進行簽名
- 獲取開發者賬戶下的team id, 上傳pkg進行公證
- 等待150s, 查看公證結果
- 對已公證的程序進行簽章


> 簽名完成后 codesign -dvvv $projectName.app 可以查看簽名信息; 但此時用 spctl -a -vvvv  $projectName.app 2>&1 |grep -v objc 檢查應該是reject狀態, 需要上傳到蘋果服務器進行公證
> 公證完成后在用spctl檢查 才會是accepted 狀態, 很多文章描述得比較粗糙. 導致有人認為簽名就能accepted .
> 簽章應該是用于離線認證, 非必要步驟.


整個流程的日志給大家參考一下: 
 1 khan@Khan-WorkMini deployd %sudo ./notarization.sh MinSizeRel
 2 Password:
 3 [CMake project]
 4 Project Name [DonnerSynths V 0.10.4]
 5 Deployd /Users/khan/Project/Cpp/build-donner-synths-Desktop_Qt_5_15_2_clang_64bit-MinSizeRel package
 6 DonnerSynths.app: signed app bundle with Mach-O thin (x86_64) [com.cc.dd.app]
 7 
 8 Executable=/Users/khan/Project/Cpp/donner-synths/deployd/DonnerSynths.app/Contents/MacOS/DonnerSynths
 9 Identifier=com.cc.dd.app
10 Format=app bundle with Mach-O thin (x86_64)
11 CodeDirectory v=20500 size=9219 flags=0x10000(runtime) hashes=277+7 location=embedded
12 Hash type=sha256 size=32
13 CandidateCDHash sha256=088f2a88da85775cd13b727ff82dc6397fe45bbd
14 CandidateCDHashFull sha256=088f2a88da85775cd13b727ff82dc6397fe45bbd167801a5438ba1256534b65a
15 Hash choices=sha256
16 CMSDigest=088f2a88da85775cd13b727ff82dc6397fe45bbd167801a5438ba1256534b65a
17 CMSDigestType=2
18 CDHash=088f2a88da85775cd13b727ff82dc6397fe45bbd
19 Signature size=9023
20 Authority=Developer ID Application: iiii (team id)
21 Authority=Developer ID Certification Authority
22 Authority=Apple Root CA
23 Timestamp=Jan 7, 2022 at 10:44:53 AM
24 Info.plist entries=14
25 TeamIdentifier=team id
26 Runtime Version=12.0.0
27 Sealed Resources version=2 rules=13 files=1196
28 Internal requirements count=1 size=184
29  End codesign 
30 
31 
32 pkgbuild: Adding component at /Users/khan/Project/Cpp/donner-synths/deployd/DonnerSynths.app
33 pkgbuild: Using timestamp authority for signature
34 pkgbuild: Signing package with identity "Developer ID Installer: iiii (team id)" from keychain /Users/khan/Library/Keychains/login.keychain-db
35 pkgbuild: Adding certificate "Developer ID Certification Authority"
36 pkgbuild: Adding certificate "Apple Root CA"
37 pkgbuild: Wrote package to DonnerSynths_V0.10.4.pkg
38 
39 Package "DonnerSynths_V0.10.4.pkg":
40    Status: signed by a developer certificate issued by Apple for distribution
41    Signed with a trusted timestamp on: 2022-01-07 02:44:56 +0000
42    Certificate Chain:
43     1. Developer ID Installer: iiii (team id)
44        Expires: 2027-01-08 01:57:26 +0000
45        SHA256 Fingerprint:
46            EA B7 AC 9A 93 E8 53 36 A2 C4 C2 05 3E 25 9E 03 E4 F1 47 EB CC 56 
47            A4 1A 50 81 25 7D 8E 68 4C D2
48        ------------------------------------------------------------------------
49     2. Developer ID Certification Authority
50        Expires: 2027-02-01 22:12:15 +0000
51        SHA256 Fingerprint:
52            7A FC 9D 01 A6 2F 03 A2 DE 96 37 93 6D 4A FE 68 09 0D 2D E1 8D 03 
53            F2 9C 88 CF B0 B1 BA 63 58 7F
54        ------------------------------------------------------------------------
55     3. Apple Root CA
56        Expires: 2035-02-09 21:40:36 +0000
57        SHA256 Fingerprint:
58            B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C 
59            68 C5 BE 91 B5 A1 10 01 F0 24
60 
61 
62 [TEAM ID: 7FAP7F8RGQ]
63 DonnerSynths [RequestUUID: 7d500295-6fb9-42c9-9225-6392d90d79ac]
64 No errors getting notarization info.
65 
66           Date: 2022-01-07 02:52:14 +0000
67           Hash: 7e67a9c9ff19ac005118979c919ad2f1c455ce76c6367f1f004eb7a8fc813c9d
68     LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma126/v4/88/86/48/88864802-9a8f-3298-dbb1-eca3bb5e0125/developer_log.json?accessKey=1641718489_3503811620240527835_%2Fx0eXAds4HsDELxjADZUUu%2BgPIcHlwg8Rjwix%2FUDtgq0EL0zekzWYRuqxVmxuMB77dWVSlrDIx8l8Tt2m%2BNS%2FFsbl5vpGv6bfKksg%2FErnX%2BI0YWo1yOVKECEBLIVS3%2B8Aeuh4zEl%2BXG1W4fddYy94YDlq6X8Jw7XnY3uDyJ1Kvw%3D
69    RequestUUID: 7d500295-6fb9-42c9-9225-6392d90d79ac
70         Status: success
71    Status Code: 0
72 Status Message: Package Approved
73 
74 Processing: /Users/khan/Project/Cpp/donner-synths/deployd/DonnerSynths_V0.10.4.pkg
75 Processing: /Users/khan/Project/Cpp/donner-synths/deployd/DonnerSynths_V0.10.4.pkg
76 The staple and validate action worked!
77 Done.




2. 附錄: 
該腳本可根據參數選擇打包成pkg 或 dmg , 并簽名 公證 簽章

USAGE: sudo ./deploy -t[target] -p[package] -s

 -t target: [debug|release|MinSizeRel]

 -p package: [dmg|pkg] 打包類型

 -s sign 是否需要簽名, 如攜帶該參數, 會自動公證簽章, 否則僅完成打包動作

  example: ./deploy -s -t release -p dmg


  1 #!/bin/bash
  2 
  3 ###########################################################################
  4     QDeployd="/Users/khan/Develop/Qt/5.15.2/clang_64/bin/macdeployqt"
  5     BUNLDE_ID="com.xxx.keyboard.app"        # bundle id
  6     USER="xxxx@xxx.com"                    # apple開發者賬戶
  7     PASSWORD="xxxx-dddd-xxx-xxxx"             # apple開發者專屬密碼(specific password) 見: https://support.apple.com/zh-cn/HT204397  在https://appleid.apple.com/ 申請
  8     CERTIFICATE="Developer ID Application: xxxx Co.,Ltd (7FAP7F8RGQ)"         # 代碼簽名證書, app 和 dmg需要
  9     INSTALLER_CERTIFICATE="Developer ID Installer: xxxx Co.,Ltd (7FAP7F8RGQ)" # 安裝包簽名證書, pkg需要
 10 ###########################################################################
 11 
 12 ###########################################################################
 13     COLOR_NORMAL="\033[0m"
 14     COLOR_BLACK="\033[1;30m"
 15     COLOR_RED="\033[1;31m"
 16     COLOR_GREEN="\033[1;32m"
 17     COLOR_YELLOW="\033[1;33m"
 18     COLOR_BLUE="\033[1;34m"
 19     COLOR_PURPLE="\033[1;35m"
 20     COLOR_WHITE="\033[1;37m"
 21 ###########################################################################
 22 
 23 
 24 getVersion(){
 25     local appVersion="0.0.0"
 26     local FindRet=$(find ../ -iname "info.h")
 27     if [ -n "$FindRet" ] ; then
 28         appVersion=$(cat $FindRet |grep -i 'VERSION' |sed 's|.*\"\([0-9\.]*\)\".*|\1|g');
 29     fi;
 30     echo "$appVersion"
 31 }
 32 
 33 getProjectType(){
 34     if [ -f "../CMakeLists.txt" ] ; then
 35         return 1;
 36     else
 37         return 0;
 38     fi;
 39 }
 40 
 41 getProjectName(){
 42     local CMAKE=$1
 43     local projectName=""
 44     if [ "$CMAKE" -eq "1" ] ; then
 45         projectName=$(cat ../CMakeLists.txt |grep -i 'Project(' | sed 's|.*(\([a-zA-Z0-9]*\)\ .*|\1|g');
 46     else 
 47         projectName=$(ls ../*.pro)
 48         projectName=$(echo "$projectName" | sed 's|../||g' | sed 's|.pro||g' );
 49     fi;
 50     echo "$projectName"
 51 }
 52 
 53 getAppPath(){
 54     local CMAKE=$1
 55     local projectName=$2
 56     local target=$3
 57     
 58     local targetPaths=""
 59     if [ "$CMAKE" -eq "1" ] ; then
 60         data="$(cat ../CMakeLists.txt.user)"
 61         count=$(xmllint --xpath 'count(//data/valuemap/valuemap/value[@key="ProjectExplorer.BuildConfiguration.BuildDirectory"])' - <<< "$data")
 62         for((index=1$index<=$countindex++)) ; do
 63             tmp=$(xmllint --xpath "(//data/valuemap/valuemap/value[@key='ProjectExplorer.BuildConfiguration.BuildDirectory'])[$index]/text()" - <<< "$data")
 64             targetPaths="$targetPaths$tmp\n"
 65         done;
 66     else 
 67         data="$(cat ../$projectName.pro.user)"
 68         count=$(xmllint --xpath 'count(//data/valuemap/valuemap/value[@key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir"])' - <<< "$data")
 69         for((index=1$index<=$countindex++)) ; do
 70             tmp=$(xmllint --xpath "(//data/valuemap/valuemap/value[@key='ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir'])[$index]/text()" - <<< "$data")
 71             targetPaths="$targetPaths$tmp\n"
 72         done;
 73     fi;
 74 
 75     local targetPath=$(echo -e "$targetPaths" |grep -E -i "$target" | head -n 1)
 76     echo "$targetPath";
 77 }
 78 
 79 printHelp() {
 80     echo -e "USAGE: $0 -t$COLOR_YELLOW[target]$COLOR_NORMAL -p$COLOR_YELLOW[package]$COLOR_NORMAL -s"
 81     echo -e " -t target: $COLOR_YELLOW[debug|release|MinSizeRel]$COLOR_NORMAL"
 82     echo -e " -p package: $COLOR_YELLOW[dmg|pkg|zip]$COLOR_NORMAL"
 83     echo -e " -s sign"
 84     echo -e "  example: $0 -s -t$COLOR_YELLOW release $COLOR_NORMAL-p$COLOR_YELLOW dmg$COLOR_NORMAL"
 85 }
 86 
 87 
 88 unMountDmg(){
 89     DMG_NAME=$1
 90     data=$(hdiutil info -plist)
 91     VOL_DEVICE=$(xmllint --xpath "//dict[contains(., '$DMG_NAME') and key='image-path']/array/dict[key='dev-entry' and contains(., 'GUID_partition_scheme')]/key[text()='dev-entry']/following-sibling::*[1]/text()" - 2>/dev/null <<< "$data")
 92     if [ "$VOL_DEVICE" ]; then
 93         echo -e "Unmount DMG$COLOR_PURPLE $VOL_DEVICE $COLOR_NORMAL"
 94         hdiutil detach $VOL_DEVICE;
 95     fi
 96 }
 97 
 98 signApp(){
 99     local appPath=$1
100     local certificate=$2
101     local entitlementsPath=$3
102     # 對qt模塊進行簽名
103     local FrameworksName=$(ls $appPath/Contents/Frameworks/ | cut -d '.' -f 1)
104     for Item in ${FrameworksName[@]}
105     do
106         codesign --force --timestamp --entitlements $entitlementsPath --sign "$certificate" $appPath/Contents/Frameworks/$Item.framework/$Item;
107     done;
108 
109     # 對插件進行簽名
110     local DylibName=$(find $appPath/Contents/PlugIns/ -name *.dylib)
111     for Item in ${DylibName[@]}
112     do
113         codesign --force --timestamp --entitlements $entitlementsPath --sign "$CERTIFICATE" $Item;
114     done;
115 
116     codesign --sign "$CERTIFICATE" --verbose=4 --timestamp -o runtime --entitlements $entitlementsPath $appPath
117 
118     echo -e ""
119     codesign -dvvv $appPath
120     echo -e "${COLOR_PURPLE}End codesign ${COLOR_NORMAL}\n\n"
121 }
122 
123 makeDmg(){
124     local appName=$1
125     local certificate=$2
126     local bundleId=$3
127     local DMG_BACKGROUND_IMG=$4
128     
129 
130     local VOL_NAME="${appName}"
131     local APP_EXE="${appName}.app/Contents/MacOS/${appName}"
132 
133     local DMG_TMP="${appName}-rw.dmg"
134     local DMG_FINAL="${appName}.dmg"
135     local STAGING_DIR="./Install"
136     
137     
138     # Check the background image DPI and convert it if it isn't 72x72
139     local _BACKGROUND_IMAGE_DPI_H=`sips -g dpiHeight ${DMG_BACKGROUND_IMG} | grep -Eo '[0-9]+\.[0-9]+'`
140     local _BACKGROUND_IMAGE_DPI_W=`sips -g dpiWidth ${DMG_BACKGROUND_IMG} | grep -Eo '[0-9]+\.[0-9]+'`
141 
142 
143     if [ $(echo " $_BACKGROUND_IMAGE_DPI_H != 72.0 " | bc) -eq 1 -o $(echo " $_BACKGROUND_IMAGE_DPI_W != 72.0 " | bc) -eq 1 ]; then
144         echo "WARNING: The background image's DPI is not 72.  This will result in distorted backgrounds on Mac OS X 10.7+."
145         echo "         I will convert it to 72 DPI for you."
146 
147         local _DMG_BACKGROUND_TMP="${DMG_BACKGROUND_IMG%.*}"_dpifix."${DMG_BACKGROUND_IMG##*.}"
148         sips -s dpiWidth 72 -s dpiHeight 72 ${DMG_BACKGROUND_IMG} --out ${_DMG_BACKGROUND_TMP}
149         DMG_BACKGROUND_IMG="${_DMG_BACKGROUND_TMP}";
150     fi
151 
152     # clear out any old data
153     rm -rf "${STAGING_DIR}" "${DMG_TMP}" "${DMG_FINAL}"
154     
155     # copy over the stuff we want in the final disk image to our staging dir
156     mkdir -p "${STAGING_DIR}"
157     cp -Rpf "${projectName}.app" "${STAGING_DIR}"  # -R復制軟鏈接 -p保留源文件修改時間和權限 -f強制覆蓋
158 
159     # figure out how big our DMG needs to be
160     #  assumes our contents are at least 1M!
161     local SIZE=`du -sh "${STAGING_DIR}" | sed 's/\([0-9]*\)M\(.*\)/\1/'`
162     # echo -e "DMG size: ${SIZE}"
163     SIZE=`echo "${SIZE} + 1.0" | bc | awk '{print int($1*1.5)}'`
164     echo -e "DMG size: ${SIZE}"
165 
166     if [ $? -ne 0 ]; then
167         echo "Error: Cannot compute size of staging dir"
168         exit;
169     fi
170     
171     # create the temp DMG file
172     hdiutil create -srcfolder "${STAGING_DIR}" -volname "${VOL_NAME}" -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${SIZE}M "${DMG_TMP}"
173     
174     echo "Created DMG: ${DMG_TMP}"
175     
176     # mount it and save the device
177     local DEVICE=$(hdiutil attach -readwrite -noverify "${DMG_TMP}" | egrep '^/dev/' | sed 1q | awk '{print $1}')
178     
179     sleep 3
180 
181     # add a link to the Applications dir
182     echo "Add link to /Applications"
183     pushd /Volumes/"${VOL_NAME}"
184     ln -s /Applications
185     popd
186     
187     # add a background image
188     mkdir /Volumes/"${VOL_NAME}"/.background
189     cp "${DMG_BACKGROUND_IMG}" /Volumes/"${VOL_NAME}"/.background/
190     
191     # tell the Finder to resize the window, set the background,
192     #  change the icon size, place the icons in the right position, etc.
193     echo '
194     tell application "Finder"
195         tell disk "'${VOL_NAME}'"
196             open
197             set current view of container window to icon view
198             set toolbar visible of container window to false
199             set statusbar visible of container window to false
200             set the bounds of container window to {400, 100, 920, 460}
201             set viewOptions to the icon view options of container window
202             set arrangement of viewOptions to not arranged
203             set icon size of viewOptions to 72
204             set background picture of viewOptions to file ".background:'${DMG_BACKGROUND_IMG}'"
205             set position of item "'${appName}'.app" of container window to {160, 205}
206             set position of item "Applications" of container window to {360, 205}
207             close
208             open
209             update without registering applications
210             delay 2
211         end tell
212     end tell
213     ' | osascript
214     
215     sync
216 
217     # unmount it
218     hdiutil detach "${DEVICE}"
219 
220     sleep 2
221     
222     # now make the final image a compressed disk image
223     echo "Creating compressed image"
224     hdiutil convert "${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "${VOL_NAME}_V${appVersion}.dmg"
225     
226     codesign -s "${certificate}" "${VOL_NAME}_V${appVersion}.dmg" -i "${bundleId}" --options runtime
227 
228     # clean up
229     rm -rf "${DMG_TMP}"
230     rm -rf "${STAGING_DIR}"
231     rm -f Applications
232 }
233 
234 makePkg(){
235     local appName=$1
236     local certificate=$2
237     local bundleId=$3
238     local version=$4
239     local DST_NAME=$5
240     pkgbuild --component ${appName}.app --install-location /Applications --sign "${certificate}" --identifier "${bundleId}" --version ${version} ${DST_NAME}
241     echo -e ""
242     pkgutil --check-signature ${DST_NAME}
243     echo -e ""
244 }
245 
246 makeZip(){
247     local appName=$1
248     local certificate=$2
249     local bundleId=$3
250     local DST_NAME=$4
251     # -y 或 --symlinks 存儲軟鏈接; -r 壓縮目錄及子目錄; -q 靜默模式
252     zip --symlinks -q -r ${DST_NAME} ${appName}.app
253 
254     codesign -s "${certificate}" "${DST_NAME}" -i "${bundleId}" --options runtime
255 
256     echo -e ""
257     codesign -dvvv "${DST_NAME}"
258     echo -e "${COLOR_PURPLE}End codesign ${COLOR_NORMAL}\n\n"
259 }
260 
261 notarization(){
262     local appName=$1
263     local USER=$2
264     local PASSWORD=$3
265     local DST_NAME=$4
266     # get TEAM_ID
267     local data=$(xcrun altool --list-providers -u "$USER" -p "$PASSWORD" --output-format xml)
268     local TEAM_ID=$(xmllint --xpath "//dict/array/dict[key='ProviderShortname']/key[text()='ProviderShortname']/following-sibling::*[1]/text()" - <<< "$data")
269     if [ "$TEAM_ID" ]; then
270         # notarization
271         echo -e "$COLOR_PURPLE[TEAM ID: $TEAM_ID]$COLOR_NORMAL"
272         local RESULT=$(xcrun altool --notarize-app --primary-bundle-id "$BUNLDE_ID" --username "$USER" --password "$PASSWORD" --asc-provider "$TEAM_ID" -t macos --file ${DST_NAME})
273         local FILTER_RESULT=$(echo -e "$RESULT" | grep RequestUUID)
274         if [ "$FILTER_RESULT" ] ; then
275             local RequestUUID=$(echo -e "$RESULT" |grep RequestUUID | awk '{print $3}')
276             echo -e "$projectName $COLOR_PURPLE[RequestUUID: $RequestUUID]$COLOR_NORMAL"
277 
278             sleep 150
279             xcrun altool --notarization-info "$RequestUUID" --username "$USER" --password "$PASSWORD"
280             ## 文件名全部轉成大寫; 
281             local TMP01=$(echo "$DST_NAME" | tr '[:lower:]' '[:upper:]')
282             local TMP02=$( echo "$TMP01" | grep -E '\.ZIP$')
283             if [ "$TMP02" ]; then
284                 echo "The validate action worked!"
285             else
286                 xcrun stapler staple ${DST_NAME}
287                 xcrun stapler validate ${DST_NAME};
288             fi
289 
290         else
291             echo -e "$projectName $COLOR_RED upload ERROR:$COLOR_NORMAL \n $RESULT";
292         fi;
293     fi;
294 }
295 
296 ###########################################################################
297     isSign="no"  ## 是否需要簽名 
298     FLAG="0"
299     package="dmg"
300     while getopts 't:p:vsh' OPT; do
301         case $OPT in
302             t)                    ## 打包目標 [debug|release|MinSizeRel]
303                 target="$OPTARG";;
304             p)                   ## 打包類型 [dmg|pkg|zip]
305                 package="$OPTARG";;
306             s)                      ## 是否簽名, 默認不簽名
307                 isSign="yes";;
308             v)
309                 echo -e $0$COLOR_PURPLE v$(getVersion)$COLOR_NORMAL;;
310             h)                      ## 幫助
311                 printHelp
312                 exit 0;;
313             ?)
314                 printHelp
315                 exit 1;;
316         esac
317         FLAG="1";
318     done
319     shift $(($OPTIND - 1))
320 
321     if [ "$FLAG" -eq "0" ]; then
322         printHelp
323         exit 1
324     fi;
325 ###########################################################################
326 
327 ###########################################################################
328     # 臨時全局變量
329     getProjectType
330     projectType=$?                                                 # 工程類型 cmake 或 qmake
331     projectName=$(echo $(getProjectName $projectType))             # 項目名
332     appVersion=$(echo $(getVersion))                               # 版本號
333     targetPath=$(echo $(getAppPath $projectType $projectName $target))  # 工程二進制輸出目錄
334 ###########################################################################
335 
336 
337 if [ "$projectType" = 1 ] ; then
338     echo -e "$COLOR_PURPLE[CMake project]$COLOR_NORMAL";
339 else 
340     echo -e "$COLOR_PURPLE[QMake project]$COLOR_NORMAL";
341 fi
342 
343 echo -e "Deployd $COLOR_PURPLE${targetPath}$COLOR_NORMAL $COLOR_YELLOW${projectName} v${appVersion}$COLOR_NORMAL ${package} package"
344 
345 rm -rf ./$projectName.app
346 cp -R ${targetPath}/${projectName}.app ./
347 
348 $QDeployd $projectName.app -always-overwrite -appstore-compliant -qmldir=../Resource
349 find $projectName.app -name '*.dSYM'|xargs rm -rf
350 
351 if [ "$package" = "dmg" ] ; then
352     DST_NAME=${projectName}_V${appVersion}.dmg
353 
354     unMountDmg $DST_NAME
355     if [ -f $DST_NAME ] ; then
356         rm -rf $DST_NAME;
357     fi
358 
359     if [ "$isSign" = "yes" ] ; then
360         signApp "$projectName.app" "${CERTIFICATE}" "Entitlements.plist" ;
361     fi
362     makeDmg "$projectName" "${CERTIFICATE}" "${BUNLDE_ID}" "background.png" 
363 
364     # 已簽名程序才可公證
365     if [ "$isSign" = "yes" ] ; then
366         notarization "$projectName" "${USER}" "${PASSWORD}" "${DST_NAME}";
367     fi
368 
369     echo 'Done.';
370 elif [ "$package" = "pkg" ] ; then
371     DST_NAME=${projectName}_V${appVersion}.pkg
372     if [ -f $DST_NAME ] ; then
373         rm -rf $DST_NAME;
374     fi
375 
376     if [ "$isSign" = "yes" ] ; then
377         signApp "$projectName.app" "${CERTIFICATE}" "Entitlements.plist" ;
378     fi;
379     makePkg "$projectName" "${INSTALLER_CERTIFICATE}" "${BUNLDE_ID}" "${appVersion}" "${DST_NAME}"
380 
381     # 已簽名程序才可公證
382     if [ "$isSign" = "yes" ] ; then
383         notarization "$projectName" "${USER}" "${PASSWORD}" "${DST_NAME}";
384     fi
385 
386     echo 'Done.';
387 elif [ "$package" = "zip" ] ; then
388     DST_NAME=${projectName}_V${appVersion}.zip
389     if [ -f $DST_NAME ] ; then
390         rm -rf $DST_NAME;
391     fi
392     if [ "$isSign" = "yes" ] ; then
393         signApp "$projectName.app" "${CERTIFICATE}" "Entitlements.plist" ;
394     fi
395 
396     makeZip "$projectName" "${CERTIFICATE}" "${BUNLDE_ID}" "${DST_NAME}"
397     # 已簽名程序才可公證
398     if [ "$isSign" = "yes" ] ; then
399         notarization "$projectName" "${USER}" "${PASSWORD}" "${DST_NAME}";
400     fi
401 
402     echo 'Done.';
403 else
404     printHelp
405     exit 1;
406 fi;

posted on 2022-01-07 12:14 Khan 閱讀(1182) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一级片在线观看| 亚洲一区二区三区高清不卡| 亚洲高清电影| 免费欧美日韩国产三级电影| 亚洲国产女人aaa毛片在线| 伊人久久婷婷| 欧美日韩精品二区| 亚洲另类视频| 久久九九国产精品| 亚洲一区网站| 欧美激情视频给我| 亚洲欧美在线一区| 亚洲国产成人精品女人久久久| 欧美理论视频| 午夜日韩激情| 亚洲精品日产精品乱码不卡| 欧美亚洲免费| 亚洲电影免费观看高清完整版| 男人的天堂成人在线| 亚洲欧美成人| 亚洲精品久久视频| 国产日韩1区| 欧美精品一卡二卡| 久久久精品五月天| 亚洲一区二区三区在线看 | 噜噜噜在线观看免费视频日韩| 99视频精品免费观看| 在线播放日韩欧美| 国产精品一区视频| 欧美日本国产| 欧美成人蜜桃| 久久久免费av| 久久精品欧美日韩| 香蕉久久a毛片| 亚洲欧美精品在线观看| 亚洲三级影院| 91久久精品美女高潮| 欧美大色视频| 久久久亚洲高清| 久久偷窥视频| 久热国产精品视频| 久久综合狠狠综合久久综合88| 久久精品中文字幕免费mv| 欧美一区二区视频免费观看 | 亚洲一区二区三区四区中文| 日韩一二在线观看| 一区二区欧美视频| 亚洲一区二区三区中文字幕在线| 亚洲美女免费精品视频在线观看| 日韩一级片网址| 亚洲一区国产视频| 欧美亚洲综合久久| 久久久久久伊人| 欧美gay视频| 国产精品视频观看| 欧美专区在线观看| 一本色道久久综合一区| 欧美日韩国产成人高清视频| 久久久国产成人精品| 欧美成人午夜剧场免费观看| 欧美日韩在线播放三区四区| 国产精品免费小视频| 国产自产v一区二区三区c| 在线观看欧美日韩国产| 久久蜜臀精品av| 欧美久久久久久久| 国产一区二区三区奇米久涩| 最新国产拍偷乱拍精品 | 欧美精品一区二区三区高清aⅴ| 欧美日韩伦理在线免费| 亚洲美女色禁图| 国产综合精品| 老巨人导航500精品| 亚洲欧美综合国产精品一区| 久久国产福利| 国产精品美腿一区在线看| 宅男在线国产精品| 99精品99| 久久在线播放| 欧美性做爰毛片| 亚洲国产一区二区在线| 亚洲欧美在线观看| 亚洲激情啪啪| 久久久人成影片一区二区三区| 欧美日韩高清免费| 在线观看亚洲精品| 久久高清一区| 日韩网站在线看片你懂的| 久久精品欧美日韩| 伊人久久成人| 久久久久国产精品一区| 欧美va亚洲va香蕉在线| 一本综合久久| 欧美午夜精品久久久| 亚洲一区二区三区高清不卡| 一本色道久久88综合日韩精品| 欧美福利视频| 宅男精品导航| 亚洲桃花岛网站| 国产欧美精品在线播放| 欧美在线资源| 久久成人久久爱| 一区在线影院| 亚洲欧洲综合另类在线| 欧美日韩国产综合网| 亚洲一区二区三区高清不卡| 亚洲午夜av在线| 精品88久久久久88久久久| 91久久精品www人人做人人爽| 国产日韩av高清| 亚洲精品国产视频| 欧美另类久久久品| 亚洲综合日韩在线| 久久久久久亚洲精品中文字幕| 国产一区91| 99这里有精品| 国产精品你懂得| 久久永久免费| 国产麻豆91精品| 久久久久久久综合色一本| 久久精品30| 亚洲一区制服诱惑| 蜜臀av在线播放一区二区三区| 午夜电影亚洲| 欧美日韩高清在线播放| 久久婷婷国产综合精品青草| 国产精品电影在线观看| 欧美福利专区| 亚洲黄色影院| 国产精品美女久久久久久2018| 久久久久国产一区二区| 免费日韩av电影| 亚洲一区综合| 久久综合中文| 久久久久在线| 美女久久网站| 久久国产精品高清| 欧美性大战久久久久久久| 亚洲大胆视频| 欧美体内she精视频| 99视频一区二区| 美女国内精品自产拍在线播放| 亚洲第一在线综合网站| 久久精品国产成人| 老色批av在线精品| 亚洲麻豆一区| 国产精品嫩草影院一区二区| 一本大道久久a久久综合婷婷 | 国产欧美一区二区三区视频| 麻豆精品视频在线观看视频| 一色屋精品视频免费看| 蜜臀av在线播放一区二区三区| 亚洲一区免费看| 国产精品久久久久久av下载红粉 | 亚洲破处大片| 欧美v国产在线一区二区三区| 亚洲高清免费在线| 国模 一区 二区 三区| 欧美激情一区二区三区| 狠狠爱www人成狠狠爱综合网| 亚洲视频axxx| 在线中文字幕不卡| 久久亚洲国产精品日日av夜夜| 久久精品五月| 一区二区高清在线| 国产日韩专区| 欧美激情视频网站| 亚洲一区国产视频| 亚洲激情图片小说视频| 午夜久久tv| 亚洲精品国偷自产在线99热| 亚洲电影第1页| 国产一区二区三区四区在线观看| 欧美在线视频一区| 久久一本综合频道| 亚洲精品偷拍| 国产精品毛片高清在线完整版| 中文一区字幕| 欧美高清在线播放| 亚洲影视在线播放| 国产在线视频欧美| 欧美香蕉大胸在线视频观看| 销魂美女一区二区三区视频在线| 欧美亚洲综合网| 国产精品wwwwww| 久久经典综合| 久久免费视频一区| 国产人成精品一区二区三| 香蕉精品999视频一区二区 | 亚洲精品视频在线播放| 欧美日韩一区精品| 香蕉久久夜色精品国产使用方法 | 香港成人在线视频| 亚洲理伦电影| 欧美成人视屏| 一本一本a久久| 在线免费观看日本一区| 国产精品毛片| 欧美片在线观看| 欧美成人精品|