codesign --force --verify --verbose --sign "Developer ID Application: XXXX. (XXXXXXX)" MMMMMM.framework
在終端輸入便可,注意MMMMMM.framework 須要是絕對路徑。xcode
codesign --force --verify --verbose --sign "Developer ID Application: XXXXXX. (XXXXX)" NNNNNNN.app
若是想驗證下APP是否簽名成功,能夠輸入下面任意一個命令:app
(1)第一條命令:用於判斷APP及全部framework是否簽名工程tcp
codesign -v --strict --deep --verbose=2 aaaaa.app
若是提示下面兩行表示成功:ui
aaaaa.app: valid on disk
aaaaa.app: satisfies its Designated Requirement
若是提示相似下面的提示,表示失敗:spa
In subcomponent /XXXX/XXXX/XXXX/ff.framework
表示這個framework簽名不合格,須要查看此framework內部文件結構是否正常等,完成以後從新進行簽名,再對APP進行簽名。
debug
(2)第二條命令:用於查看APP簽名信息及嵌入到APP的dylib和framework等code
codesign -d --deep --verbose=2 -r- aaaaa.app
提示以下表示成功:component
(3)第三條命令:orm
spctl --assess -vv NNNNN.app
提示以下表示成功:blog
aaaaa.app: accepted source=Developer ID origin=Developer ID Application: XXXXXXXXX. (XXXXXX)
xcode 提示 " framework/Versions/A:bundle format unrecognized, invalid, or unsuitable" ,
說明當前framework不符合apple官方對framework這種bundle的格式要求。查看Versions/A文件夾下爲空。
以QtConcurrent.framework(Qt 5.5.1版本)爲例說明問題,提示的framework結構爲:
因爲發版時都是基於release版本編譯,所以移除根目錄下QtConcurrent_debug和QtConcurrent_debug.prl文件,而後從新對當前framework進行簽名處理,
此時會提示「Unsealed contents present in the root directory of an embedded framework」,說明在framework的根目錄下存在不符合要求的文件,
此時除了軟鏈接文件,就剩餘QtConcurrent.prl文件,經查閱發現此文件用於在連接時查找庫的依賴關係,所以此文件不能刪除。
那不刪除又沒法簽名成功,該如何處理呢?
QtConcurrent.framework根目錄下沒有了QtConcurrent.prl,而且在/5/目錄下生成了一個名爲 _CodeSignature的文件夾,表示當前framework簽名成功。
對於APP所依賴全部Qt的framework進行上述處理,而對於其餘dylib文件則比較簡單,直接輸入簽名命令進行簽名便可。
須要特別注意的是QtWebEngineCore.framework,對此進行簽名以前,須要先對/Versions/5/Helpers/QtWebEngineProcess.app進行簽名。
等全部依賴的庫簽名成功後,再對APP進行簽名:
codesign --force --verify --verbose --sign "Developer ID Application: XXXXX (XXXXX)" aaaaaa.app
其中aaaaa.app表明app的絕對路徑若是app簽名也成功,那麼在APP/Contents根目錄下會多出一個_CodeSignature文件夾和embedded.provisionfile文件。
爲了方便編譯,本身封裝了一個腳本(codesign_framework_test.sh),在xcode的配置便可,以下圖所示。
codesign_frameworks_test.sh的內容爲:
1 #!/bin/sh 2 3 # WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY! 4 # FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle") 5 6 echo "------start to process unseable files in framework ----" 7 ITEMS="" 8 9 echo "build dir:" 10 echo $TARGET_BUILD_DIR 11 12 FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 14 echo "Framework path:" 15 echo $FRAMEWORKS_DIR 16 17 # Prefer the expanded name, if available. 18 CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 19 if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then 20 # Fall back to old behavior. 21 CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}" 22 fi 23 24 echo "Identity:" 25 echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}" 26 27 if [ -d "$FRAMEWORKS_DIR" ] ; then 28 # FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework") 29 FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle") 30 RESULT=$? 31 if [[ $RESULT != 0 ]] ; then 32 exit 1 33 fi 34 ITEMS="${FRAMEWORKS}" 35 fi 36 37 echo "Found:" 38 echo "${ITEMS}" 39 40 for ITEM in $ITEMS; 41 do 42 43 framework_filepath="${ITEM##*/}" 44 45 # 不帶後綴的文件名 46 framework_filename="${framework_filepath%.*}" 47 48 # 帶後綴名的文件名 49 current_framework_name="${framework_filepath##*/}" 50 echo "============================:"$current_framework_name 51 52 # 後綴名 53 extension=${ITEM##*.} 54 55 if [ "$extension" != "framework" ] 56 then 57 # 簽名 58 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${ITEM}" 59 continue 60 fi 61 62 zip_archive_framework="ZipArchive.framework" 63 64 #判斷字符串是否相等 65 if [ "$zip_archive_framework" == "$current_framework_name" ] 66 then 67 #zip_archive_framework 須要單獨處理 68 echo "[ process ZipArchive.framework ]" 69 70 headers_folder="${ITEM}/Headers" 71 modules_folder="${ITEM}/Modules" 72 resources_folder="${ITEM}/Resources" 73 current_folder="${ITEM}/Versions/Current" 74 75 rm -rf $headers_folder 76 rm -rf $modules_folder 77 rm -rf $resources_folder 78 rm -rf $current_folder 79 rm "${ITEM}/ZipArchive" 80 81 ln -s "${ITEM}/Versions/A" $current_folder 82 ln -s "${ITEM}/Versions/A/Headers" $headers_folder 83 ln -s "${ITEM}/Versions/A/Modules" $modules_folder 84 ln -s "${ITEM}/Versions/A/Resources" $resources_folder 85 ln -s "${ITEM}/Versions/A/ZipArchive" "${ITEM}/ZipArchive" 86 87 # 簽名 88 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${ITEM}/Versions/A" 89 else 90 # debug file 91 debug_name="${framework_filename}_debug" 92 framework_debug="${ITEM}/${debug_name}" 93 94 # debug prl file 95 debug_prl_name="${framework_filename}_debug.prl" 96 framework_debug_prl="${ITEM}/${debug_prl_name}" 97 98 echo "${framework_debug} deleting >>>" 99 echo "${framework_debug_prl} deleting >>>" 100 101 # delete two files 102 rm $framework_debug 103 rm $framework_debug_prl 104 105 # 移除A文件夾,不然APP簽名失敗 106 rm -rf "${ITEM}/Versions/A" 107 108 resources_folder="${ITEM}/Versions/5/Resources" 109 echo $resources_folder 110 release_prl_name="${framework_filename}.prl" 111 framework_release_prl="${ITEM}/${release_prl_name}" 112 echo $framework_release_prl 113 echo "move ${framework_release_prl} to Resources folder::" 114 mv $framework_release_prl $resources_folder 115 116 if [ "QtWebEngineCore" == "$framework_filename" ] 117 then 118 QtWebEngineProcess_app="${ITEM}/Versions/5/Helpers/QtWebEngineProcess.app" 119 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${QtWebEngineProcess_app}" 120 fi 121 # 簽名 122 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${ITEM}" 123 fi 124 done 125 126 MacOS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/MacOS" 127 MacOS_ITEMS="" 128 129 if [ -d "$MacOS_DIR" ] ; then 130 MacOSLibs=$(find "${MacOS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle") 131 RESULT=$? 132 if [[ $RESULT != 0 ]] ; then 133 exit 1 134 fi 135 MacOS_ITEMS="${MacOSLibs}" 136 fi 137 138 echo "MacOS_Found:" 139 echo "${MacOS_ITEMS}" 140 141 for MacOS_ITEM in $MacOS_ITEMS; 142 do 143 framework_filepath="${MacOS_ITEM##*/}"] 144 # 帶後綴名的文件名 145 current_framework_name="${framework_filepath##*/}" 146 echo "============================:"$current_framework_name 147 148 # 簽名 149 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${MacOS_ITEM}" 150 done 151 152 # 特殊處理的 etcpack 和 convert 153 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${MacOS_DIR}/etcpack" 154 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${MacOS_DIR}/convert" 155 156 #app 157 PROJECT_NAME="${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}" 158 echo "PROJECT_NAME:" 159 echo $PROJECT_NAME 160 161 #對APP簽名 162 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${PROJECT_NAME}" 163 164 #用於判斷APP及全部framework是否簽名工程 165 codesign -v --strict --deep --verbose=2 "${PROJECT_NAME}"
注意:
1. 若是未使用ZipArchive.framework,則不須要特殊處理。
2.若是未使用etcpack和convert,也無需簽名處理。