天天看點

29 CMake 知識點 - Android Studio (筆記)

Android Ndk 學習筆記(目錄)

# 最低支援的版本,注意:這裡并不能代表最終的版本,最終版本在app.build.gradle中設定的
cmake_minimum_required(VERSION 3.10.2)
           

build.gradle 中是cmake 的版本

29 CMake 知識點 - Android Studio (筆記)
# 目前工程名,以前的舊版本,是沒有設定的,這個可以設定,也可以不設定
project("ndk28_cmake")
           
# 批量導入 cpp c源檔案
# file 可以定義一個變量 SOURCE, GLOB(使用GLOB從源樹中收集源檔案清單,就可以開心的 *.cpp *.c *.h)
# https://www.imooc.com/wenda/detail/576408
file(GLOB SOURCE *.cpp *.c *.h *.hpp)
           
# 添加一個庫(動态庫SHARED,靜态庫STATIC)
add_library(native-lib # 庫的名字 ---> libnative-lib.so
             SHARED  # 動态庫
            # cpp的源檔案:把cpp源檔案編譯成 libnative-lib.so 庫
             ${SOURCE}
        )
           
# 查找一個 NDK工具中的 動态庫(liblog.so)

# 思考:我如何知道 哪些庫是可以寫的,你怎麼知道些一個log就可以?
# 答:請檢視 D:\Android\Sdk\ndk\21.4.7075529\build\cmake\system_libs.cmake

# 思考:D:\Android\Sdk\ndk\21.0.6113669\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\arm-linux-androideabi\16\liblog.so
# 答:你怎麼知道是在 21.4.7075529?,arm-linux-androideabi?,16?
# 答:?1(因為local.properties知道了NDK版本,或者是你目前的NDK版本)
# 答:?2(因為我的手機是arm32的 是以 == arm-linux-androideabi 而且還我運作過)
# 答:?3(因為 minSdkVersion 16)
find_library(log-lib
              log )
           
# native-lib是我們的總庫,也就是我們在 apk/lib/libnative-lib.so
# 然後 把log庫連結到 總庫中去,總庫的cpp代碼就可以使用 android/log.h的庫實作代碼了
target_link_libraries(native-lib # 被連結的總庫
                       ${log-lib} # 連結的具體庫

                     # getndk
        )
           
# TODO CMake變量
# 聲明變量:set(變量名 變量值)
set(var 666)
# 引用變量:message 指令用來列印
message("var = ${var}")
# CMake中所有變量都是string類型。可以使用set()和unset()指令來聲明或移除一個變量
# 移除變量
unset(var)
message("my_var = ${var}") # 會取不到值,因為被移除了

# TODO CMake清單(lists)
# 聲明清單:set(清單名 值1 值2 ... 值N) 或 set(清單名 "值1;值2;...;值N")
set(list_var 1 2 3 4 5) # 字元串清單呢? CMake中所有變量都是string類型
# 或者
set(list_var2 "1;2;3;4;5") # 字元串清單呢?  CMake中所有變量都是string類型

message("list_var = ${list_var}")
message("list_var2 = ${list_var2}")

# TODO CMake流程控制-條件指令
# true(1,ON,YES,TRUE,Y,非0的值)
# false(0,OFF,NO,FALSE,N,IGNORE,NOTFOUND)
set(if_tap OFF) # 定義一個變量if_tap,值為false
set(elseif_tap ON) # 定義一個變量elseif_tap,值為ture

if(${if_tap})
    message("if")
elseif(${elseif_tap})
    message("elseif")
else(${if_tap}) # 可以不加入 ${if_tap}
    message("else")
# endif(${if_tap}) # 結束if
endif() # 結束if 可以不加
# 注意:elseif和else部分是可選的,也可以有多個elseif部分,縮進和空格對語句解析沒有影響

# TODO CMake流程控制-循環指令
set(a "")
#  a STREQUAL "xxx"(a等不等xxx,不等于)
#  NOT == !
while(NOT a STREQUAL "xxx")
    set(a "${a}x")
    message(">>>>>>a = ${a}")
endwhile()
#[[ 注意:
break()指令可以跳出整個循環
continue()可以繼續目前循環
]]

foreach(item 1 2 3)
    message("1item = ${item}")
endforeach(item) # 結束for

foreach(item RANGE 2) # RANGE 預設從0開始, 是以是:0 1 2
    message("2item = ${item}")
endforeach(item)

foreach(item RANGE 1 6 2) #  1 3 5 每次跳級2
    message("3item = ${item}")
endforeach(item)

set(list_va3 1 2 3) # 清單
# foreach(item IN LISTS ${list_va3}) 沒有報錯,沒有循環
foreach(item IN LISTS list_va3)
    message("4item = ${item}")
endforeach(item)

# TODO CMake自定義函數  Shell的函數很類似
#[[
ARGC:表示傳入參數的個數
ARGV0:表示第一個參數,ARGV1、ARGV2以此類推即可
ARGV:表示所有參數
]]
function(num_method n1 n2 n3)
    message("call num_method method")
    message("n1 = ${n1}")
    message("n2 = ${n2}")
    message("n3 = ${n3}")
    message("ARGC = ${ARGC}")
    message("arg1 = ${ARGV0} arg2 = ${ARGV1} arg3 = ${ARGV2}")
    message("all args = ${ARGV}")
endfunction(num_method)
num_method(1 2 3) # 調用num_method函數

# 靜态庫和動态庫本質
           
// AS gradle:3.x 舊版本沒有任何問題
        // 新版本的才有 gradle:4.2.0,自動去尋找jniLibs檔案夾 處理和優化 ,舊版本沒有任何問題
        // 編譯報錯: If you are using jniLibs and CMake IMPORTED targets, see
        // 解決方案如下:
        // https://blog.csdn.net/qq_33750826/article/details/107518573
        // 在子產品的build.gradle中設定第三方庫的加載路徑:
        // 在gradle plugln 4.0開始,無需指定第三庫加載路徑,gradle自動會幫助我們尋找,否則會出現以下錯
        sourceSets.main.jniLibs.srcDirs = ['libs']
           
29 CMake 知識點 - Android Studio (筆記)
# 批量導入 cpp c源檔案
file(GLOB SOURCE ${CMAKE_SOURCE_DIR}/cpp/*.cpp ${CMAKE_SOURCE_DIR}/cpp/*.c)


           
# TODO 方式一:推薦的方式
#[[
# 第一步:導入fmod頭檔案
include_directories("${CMAKE_SOURCE_DIR}/cpp/inc")
# 第二步:導入庫檔案 (方式一)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/jniLibsaaa/${CMAKE_ANDROID_ARCH_ABI}")
# 第三步連結到總庫中去
target_link_libraries( # native-lib是我們的總庫
        native-lib # 被連結的總庫
        log # 自動尋找  # 具體的庫 連結到 libnative-lib.so裡面去
        fmod # 具體的庫 連結到 libnative-lib.so裡面去
        fmodL # 具體的庫 連結到 libnative-lib.so裡面去
        )
]]

           
# TODO 方式二:以前更多使用的方式,老程式員使用的方式
#[[
# 第一步:導入fmod頭檔案
include_directories("${CMAKE_SOURCE_DIR}/cpp/inc")
# 第二步:導入庫檔案 (方式二)
add_library(fmod SHARED IMPORTED)
set_target_properties(fmod PROPERTIES
        IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/jniLibsaaa/${CMAKE_ANDROID_ARCH_ABI}/libfmod.so)

add_library(fmodL SHARED IMPORTED)
set_target_properties(fmodL PROPERTIES
        IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/jniLibsaaa/${CMAKE_ANDROID_ARCH_ABI}/libfmodL.so)

# 第三步連結到總庫中去
target_link_libraries( # native-lib是我們的總庫
        native-lib # 被連結的總庫
        log # 自動尋找  # 具體的庫 連結到 libnative-lib.so裡面去
        fmod # 具體的庫 連結到 libnative-lib.so裡面去
        fmodL # 具體的庫 連結到 libnative-lib.so裡面去
        )
]]
           
## OFF=0=false    ON=1=true
# set(isSTATIC OFF)
set(isSTATIC ON)

if(${isSTATIC})
    # 導入靜态庫
    add_library(getndk STATIC IMPORTED)
    # 開始真正導入 靜态庫   System.loadLibrary("getndk"); // 如果是動态庫,這裡需要加載,否則注釋
    set_target_properties(getndk PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/cpp/libgetndk.a)
    message("isSTATIC == static")
else(${isSTATIC})
    # 導入動态庫
    add_library(getndk SHARED IMPORTED)
    # 開始真正導入 動态庫  System.loadLibrary("getndk"); // 如果是動态庫,這裡需要加載,否則注釋
    set_target_properties(getndk PROPERTIES
            IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/jniLibsaaa/${CMAKE_ANDROID_ARCH_ABI}/libgetndk.so)
    message("isSTATIC == shared")

endif(${isSTATIC})
           
#引入get子目錄下的CMakeLists.txt
add_subdirectory(${CMAKE_SOURCE_DIR}/cpp/libget)

#引入count子目錄下的CMakeLists.txt
add_subdirectory(${CMAKE_SOURCE_DIR}/cpp/libcount)

target_link_libraries( # native-lib是我們的總庫
        native-lib # 被連結的總庫
        log # 自動尋找  # 具體的庫 連結到 libnative-lib.so裡面去
        get # 具體的庫 連結到 libnative-lib.so裡面去
        count # 具體的庫 連結到 libnative-lib.so裡面去
        )

           
29 CMake 知識點 - Android Studio (筆記)
29 CMake 知識點 - Android Studio (筆記)