背景:
需要把Linux下的C/C++代碼移植到iOS平臺下,iOS APP鏈接編譯的靜態庫和動態庫進行測試。
工具準備:
mac一臺
cmake
xcode
github上有一個iOS版的Cmake編譯工具鏈:ios-cmake
基於該Cmake編譯工具鏈將C/C++代碼編譯成iOS平臺可用的靜態庫或者動態庫。
編譯
- 進入/C/C++源碼目錄下,新建ios.toolchain.cmake文件編輯內容如:ios.toolchain.cmake
- 接着繼續新建CMakeLists.txt
vi CMakeLists.txt
#注:此處gmhelper爲我編譯的靜態庫名字,需要替換
#DROOT是系統變量,主要指定頭文件和鏈接庫的路徑 此處可替換成自己對應路徑
cmake_minimum_required(VERSION 3.2)
project (gmhelper C CXX)
MESSAGE( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )
# 工程名
set(PROJECT_NAME gmhelper)
# 源文件
# aux_source_directory爲包含指定目錄下所有的源文件
# 若不需要包含所有的源文件,則使用set定義,如:set(SRC_FILES 1.cpp 2.cpp)
# aux_source_directory(. SRC_FILES)
set(SRC_FILES
xxx1.cpp
xxx2.cpp)
# 頭文件
# 若指定多個目錄,使用空格分隔 .表示當前項目路徑
include_directories($ENV{DROOT}/inc .)
# 編譯時鏈接路徑 此處對不同架構時的鏈接路徑做了一些處理(如果不需要鏈接其他庫可以註釋掉)
if(${ARCHS} STREQUAL "arm64")
set(LIB_DIR ios_arm64_r)
elseif(${ARCHS} STREQUAL "armv7")
set(LIB_DIR ios_armv7_r)
elseif(${ARCHS} STREQUAL "armv7s")
set(LIB_DIR ios_armv7s_r)
elseif(${ARCHS} STREQUAL "i386")
set(LIB_DIR ios_i386_r)
elseif(${ARCHS} STREQUAL "x86_64")
set(LIB_DIR ios_x86_64_r)
endif()
link_directories($ENV{DROOT}/bin/${LIB_DIR})
# 生成目標 STATIC和ARCHIVE對應靜態庫 SHARED和LIBRARY對應動態庫
add_library(${PROJECT_NAME} STATIC ${SRC_FILES})
# 鏈接/安裝
target_link_libraries(${PROJECT_NAME} pthread dl)
- 新建build目錄用於存放編譯輸出文件
mkdir build
cd build
#注:-DENABLE_BITCODE=FALSE 此處默認將bitcode模式關閉 如果鏈接的第三方庫支持bitcode模式可以不加-DENABLE_BITCODE=FALSE
cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../ios.toolchain.cmake -DPLATFORM=OS64 -DENABLE_BITCODE=FALSE
#注:gmhelper.xcodeproj 可以通過xcode打開進行繼續編譯
#不過也可以繼續選擇命令行編譯 (需要編譯Debug版將Release替換即可)
cmake --build . --config Release
- 此時Release-iphonesimulator目錄裏會生成編譯好的靜態庫(動態庫編譯只需將CMakeLists.txt裏add_library的STATIC改爲SHARED即可)
- 結合-DPLATFORM以及-DARCHS我們可以編譯輸出任意架構的庫
#-DPLATFORM編譯參數
Set -DPLATFORM to "SIMULATOR" to build for iOS simulator 32 bit (i386) DEPRECATED
Set -DPLATFORM to "SIMULATOR64" (example above) to build for iOS simulator 64 bit (x86_64)
Set -DPLATFORM to "OS" to build for Device (armv7, armv7s, arm64)
Set -DPLATFORM to "OS64" to build for Device (arm64)
Set -DPLATFORM to "OS64COMBINED" to build for Device & Simulator (FAT lib) (arm64, x86_64)
Set -DPLATFORM to "TVOS" to build for tvOS (arm64)
Set -DPLATFORM to "TVOSCOMBINED" to build for tvOS & Simulator (arm64, x86_64)
Set -DPLATFORM to "SIMULATOR_TVOS" to build for tvOS Simulator (x86_64)
Set -DPLATFORM to "WATCHOS" to build for watchOS (armv7k, arm64_32)
Set -DPLATFORM to "WATCHOSCOMBINED" to build for watchOS & Simulator (armv7k, arm64_32, i386)
Set -DPLATFORM to "SIMULATOR_WATCHOS" to build for watchOS Simulator (i386)
# -DARCHS 可以指定編譯某種架構的庫
-DARCHS=armv7 則可以只編譯armv7架構的庫
鏈接
- 現在我們可以通過xcode新建一個app來測試編譯的靜態庫或者動態庫.
首先xcode新建一個項目
- 配置項目設置(我使用的是Release版的庫,結合自身進行更改)
-
指定頭文件路徑和庫鏈接路徑
-
添加鏈接的靜態庫和動態庫 (注:如果鏈接動態庫需要在Copy Files 裏將動態庫添加進去 否則運行app時會出現image can not find)
- #include頭文件以及代碼調用
-
此處確保運行與鏈接版本的一致性
-
運行app時出現引用C++標準庫頭文件錯誤
-
將.m文件更改爲.mm
OK,APP運行成功。