一、簽名處理的流程
codesign --force --verify --verbose --sign "Developer ID Application: XXXX. (XXXXXXX)" MMMMMM.framework
在終端輸入即可,注意MMMMMM.framework 需要是絕對路徑。
codesign --force --verify --verbose --sign "Developer ID Application: XXXXXX. (XXXXX)" NNNNNNN.app
二、驗證APP是否簽名成功
如果想驗證下APP是否簽名成功,可以輸入下面任意一個命令:
(1)第一條命令:用於判斷APP及所有framework是否簽名工程
codesign -v --strict --deep --verbose=2 aaaaa.app
如果提示下面兩行表示成功:
aaaaa.app: valid on disk
aaaaa.app: satisfies its Designated Requirement
如果提示類似下面的提示,表示失敗:
In subcomponent /XXXX/XXXX/XXXX/ff.framework
表示這個framework簽名不合格,需要查看此framework內部文件結構是否正常等,完成之后重新進行簽名,再對APP進行簽名。
(2)第二條命令:用於查看APP簽名信息及嵌入到APP的dylib和framework等
codesign -d --deep --verbose=2 -r- aaaaa.app
提示如下表示成功:
(3)第三條命令:
spctl --assess -vv NNNNN.app
提示如下表示成功:
aaaaa.app: accepted source=Developer ID origin=Developer ID Application: XXXXXXXXX. (XXXXXX)
三、Qt Framework/dylib文件簽名失敗問題
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 echo ">>>>>>>>start to process unseable files in framework <<<<<<" 5 ITEMS="" 6 7 echo "build dir:" 8 echo $TARGET_BUILD_DIR 9 10 FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 11 12 echo "Framework path:" 13 echo $FRAMEWORKS_DIR 14 15 # Prefer the expanded name, if available. 16 CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 17 if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then 18 # Fall back to old behavior. 19 CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}" 20 fi 21 22 echo "Identity:" 23 echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}" 24 25 if [ -d "$FRAMEWORKS_DIR" ] ; then 26 FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle") 27 RESULT=$? 28 if [[ $RESULT != 0 ]] ; then 29 exit 1 30 fi 31 ITEMS="${FRAMEWORKS}" 32 fi 33 34 echo "Framworks_Found:" 35 36 for ITEM in $ITEMS; 37 do 38 framework_filepath="${ITEM##*/}" 39 # file name no ext 40 framework_filename="${framework_filepath%.*}" 41 # file name with ext 42 current_framework_name="${framework_filepath##*/}" 43 echo "**************:"$current_framework_name 44 # ext 45 extension=${ITEM##*.} 46 47 if [ "$extension" != "framework" ] 48 then 49 # code sign 50 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${ITEM}" 51 continue 52 fi 53 # debug file 54 debug_name="${framework_filename}_debug" 55 framework_debug="${ITEM}/${debug_name}" 56 57 # debug prl file 58 debug_prl_name="${framework_filename}_debug.prl" 59 framework_debug_prl="${ITEM}/${debug_prl_name}" 60 61 echo "${framework_debug} deleting >>>" 62 echo "${framework_debug_prl} deleting >>>" 63 64 # delete files 65 rm $framework_debug 66 rm $framework_debug_prl 67 68 # delete folder 69 rm -rf "${ITEM}/Versions/A" 70 71 resources_folder="${ITEM}/Versions/5/Resources" 72 echo $resources_folder 73 release_prl_name="${framework_filename}.prl" 74 framework_release_prl="${ITEM}/${release_prl_name}" 75 echo $framework_release_prl 76 echo "move ${framework_release_prl} to Resources folder::" 77 mv $framework_release_prl $resources_folder 78 79 if [ "QtWebEngineCore" == "$framework_filename" ] 80 then 81 QtWebEngineProcess_app="${ITEM}/Versions/5/Helpers/QtWebEngineProcess.app" 82 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${QtWebEngineProcess_app}" 83 fi 84 # code sign 85 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${ITEM}" 86 done 87 88 MacOS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/MacOS" 89 MacOS_ITEMS="" 90 91 if [ -d "$MacOS_DIR" ] ; then 92 MacOSLibs=$(find "${MacOS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle") 93 RESULT=$? 94 if [[ $RESULT != 0 ]] ; then 95 exit 1 96 fi 97 MacOS_ITEMS="${MacOSLibs}" 98 fi 99 100 echo "MacOSItems:" 101 for MacOS_ITEM in $MacOS_ITEMS; 102 do 103 framework_filepath="${MacOS_ITEM##*/}"] 104 # file name with ext 105 current_framework_name="${framework_filepath##*/}" 106 echo "**************:"$current_framework_name 107 # code sign 108 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${MacOS_ITEM}" 109 done 110 111 PROJECT_NAME="${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}" 112 echo $PROJECT_NAME 113 #code sign app 114 codesign --force --verify --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${PROJECT_NAME}" 115 116 #用於判斷是否簽名 117 codesign -v --strict --deep --verbose=2 "${PROJECT_NAME}"
注意:
1. 如果未使用ZipArchive.framework,則不需要特殊處理。
2.如果未使用etcpack和convert,也無需簽名處理。