C/C++移植iOS(CMake編譯與鏈接)

背景:
需要把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運行成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章