Qt Framework 問題之 framework/Versions/A:bundle format unrecognized, invalid, or unsuitable

在解決標題提到的問題以後,先來介紹下Qt Framework一些基本知識。
基於QT的Mac端工程,在打包時須要對全部須要嵌入到APP的framework及dylib文件進行手動簽名處理。

1、簽名處理的流程

1. 先編譯工程生成APP。
2. 對全部framework/dylib進行簽名,命令爲:
codesign --force --verify --verbose --sign "Developer ID Application: XXXX. (XXXXXXX)" MMMMMM.framework

在終端輸入便可,注意MMMMMM.framework 須要是絕對路徑。xcode

3. 對全部framework執行簽名後,對app進行簽名處理:
codesign --force --verify --verbose --sign "Developer ID Application: XXXXXX. (XXXXX)" NNNNNNN.app
在終端輸入便可,注意NNNNNNN.app是絕對路徑。

2、驗證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)

3、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.prl移動到Resources(軟鏈接的文件夾)文件夾中,此時進行簽名OK,簽名成功後,文件目錄爲:
 

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文件。

 

4、處理腳本

 

爲了方便編譯,本身封裝了一個腳本(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,也無需簽名處理。

相關文章
相關標籤/搜索