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

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 閱讀(1158) 評論(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>
            欧美国产日韩视频| 亚洲一区二区三区精品在线观看 | 99re在线精品| 亚洲欧美日本精品| 免费高清在线一区| 亚洲一区二区视频| 国产视频一区在线| 亚洲视频在线观看视频| 久久综合国产精品| 亚洲欧美日韩区| 欧美视频在线观看 亚洲欧| 亚洲电影免费观看高清完整版| 亚洲天堂免费观看| 亚洲在线中文字幕| 欧美日韩三级电影在线| 91久久夜色精品国产网站| 午夜一区在线| 在线亚洲欧美视频| 欧美日韩精品免费观看| 日韩视频中午一区| 亚洲一区区二区| 亚洲电影免费观看高清完整版在线观看| 亚洲高清二区| 亚洲欧美国产毛片在线| 欧美激情一级片一区二区| 欧美一区二区三区免费视| 欧美亚洲第一区| 日韩视频专区| 一区二区三区欧美日韩| 欧美日韩成人一区二区| 欧美综合国产精品久久丁香| 午夜精品视频| 国产欧美三级| 久久免费少妇高潮久久精品99| 亚洲一区二区在线视频| 亚洲国内精品在线| 欧美激情自拍| 国产欧美欧美| 日韩视频第一页| 欧美日韩午夜剧场| 免费91麻豆精品国产自产在线观看| 欧美日韩亚洲免费| 亚洲国产中文字幕在线观看| 欧美韩日视频| 久久最新视频| 欧美人与禽性xxxxx杂性| 亚洲一区二区三区免费在线观看| 亚洲午夜一区| 黑人操亚洲美女惩罚| 奶水喷射视频一区| 欧美日韩国产欧| 欧美激情a∨在线视频播放| 国产日韩欧美自拍| avtt综合网| 国产综合18久久久久久| 欧美高清自拍一区| 国产精品扒开腿爽爽爽视频| 亚洲国产精品久久久久秋霞不卡| 韩国欧美一区| 久久成人免费日本黄色| 一本久久a久久精品亚洲| 亚洲女性喷水在线观看一区| 亚洲午夜精品在线| 国产精品二区影院| 欧美大色视频| 1000部国产精品成人观看| 欧美主播一区二区三区美女 久久精品人| 在线观看欧美成人| 一区二区三区日韩欧美| 在线中文字幕一区| 久久久久综合| 亚洲午夜羞羞片| 欧美天堂在线观看| 亚洲图片欧美日产| 欧美在线视频一区| 国产一区二区三区电影在线观看 | 亚洲伦理久久| 午夜精品久久久久久久男人的天堂 | 免费欧美高清视频| 久久久久.com| 欧美日韩亚洲综合| 亚洲欧美日韩在线综合| 久久精品最新地址| 亚洲午夜在线观看| 亚洲黄色一区| 欧美三区在线视频| 亚洲欧美日韩一区二区| 久久综合久久综合这里只有精品| 最新日韩欧美| 欧美日韩一区二区在线视频| 亚洲欧美韩国| 欧美激情在线播放| 午夜精品在线观看| 欧美成人精品福利| 欧美www视频| 中国av一区| 国内外成人免费激情在线视频网站 | 欧美亚洲一区二区在线观看| 在线观看免费视频综合| 欧美三级精品| 久久九九国产精品怡红院| 久久国产88| 一本久久青青| 在线成人免费观看| 国产精品久久久久久久久搜平片| 亚洲美女av电影| 一区二区三区日韩欧美| 国产一区二区三区高清| 欧美午夜精品久久久久久人妖 | 中国亚洲黄色| 欧美高清视频一区二区| 性欧美1819sex性高清| 亚洲免费电影在线观看| 国产一区二区日韩精品| 国产精品黄视频| 欧美激情va永久在线播放| 欧美主播一区二区三区| 亚洲性夜色噜噜噜7777| 91久久精品美女| 亚洲午夜精品17c| 亚洲国产va精品久久久不卡综合| 欧美成人国产一区二区| 久久爱另类一区二区小说| 亚洲天堂成人在线观看| 91久久久国产精品| 欧美国产日韩一区二区| 久久综合99re88久久爱| 欧美中文字幕久久| 午夜在线视频观看日韩17c| 在线视频欧美一区| 亚洲美女性视频| 亚洲福利视频网| 在线不卡亚洲| 伊人久久婷婷色综合98网| 国产在线观看精品一区二区三区| 国产精品永久免费在线| 久久这里只有| 一区二区冒白浆视频| 91久久国产综合久久| 亚洲第一在线综合在线| 欧美国产免费| 亚洲高清视频的网址| 欧美激情中文字幕一区二区| 欧美激情一二三区| 91久久中文字幕| 99re视频这里只有精品| 99精品欧美一区| 亚洲视频一区| 午夜精品电影| 久久国产日本精品| 久久嫩草精品久久久精品| 一区二区三区 在线观看视| 在线亚洲免费视频| 亚洲欧美一级二级三级| 欧美一区二区在线播放| 久久精品视频导航| 欧美日韩精品免费| 亚洲免费视频在线观看| 午夜欧美理论片| 久久网站热最新地址| 欧美成熟视频| 亚洲美女电影在线| 亚洲伊人伊色伊影伊综合网| 亚洲免费网址| 免费成人av资源网| 羞羞答答国产精品www一本| 欧美在线视频一区二区三区| 久久亚洲午夜电影| 欧美日韩成人在线播放| 国产美女精品视频| 亚洲国产婷婷香蕉久久久久久| 日韩一区二区精品视频| 欧美在线播放视频| 亚洲欧美日韩精品久久久久| 久久精品一区二区三区四区| 欧美韩国一区| 亚洲男人影院| 久久综合亚州| 国产精品一区二区三区久久久| 国内精品国语自产拍在线观看| 日韩视频免费| 久久久亚洲精品一区二区三区 | 亚洲四色影视在线观看| 久久久国产精品一区二区三区| 亚洲激情六月丁香| 欧美一区二区三区视频| 欧美日韩视频在线第一区| 激情久久五月| 在线观看一区欧美| 午夜伦欧美伦电影理论片| 欧美福利视频网站| 欧美一级网站| 国产精品成人免费| 日韩一区二区久久| 欧美1区2区3区| 午夜日韩在线| 国产精品国产三级国产专播品爱网| 136国产福利精品导航| 久久xxxx| 亚洲女人小视频在线观看|