在寫這篇文章之前開始是想一些shell腳本與Makefile的一些基礎(chǔ)語法知識(shí)猎拨。但是又覺得太過基礎(chǔ)炼蛤。關(guān)于Liunx shell腳本可以看看教程http://c.biancheng.net/linux_tutorial/ CMake是一種跨平臺(tái)編譯工具戏罢,CMake主要是編寫CMakeLists.txt文件乍狐,然后通過cmake命令將CMakeLists.txt文件轉(zhuǎn)化為make所需要的Makefile文件肚逸,最后用make命令編譯源碼生成可執(zhí)行程序或者庫文件认境。實(shí)際項(xiàng)目中的C/C++文件不計(jì)其數(shù)、文件放置的位置也不同课竣,Makefile定義了一系列的規(guī)則來指定嘉赎,哪些文件需要先編譯置媳,哪些文件需要后編譯,哪些文件需要重新編譯公条,甚至于進(jìn)行更復(fù)雜的功能操作拇囊。實(shí)現(xiàn)自動(dòng)化的編譯。
CMake方式編譯生成庫文件
以簡單的例子來來看看CMake的語法,創(chuàng)建一個(gè) test項(xiàng)目靶橱,項(xiàng)目結(jié)構(gòu)如下
├── test目錄
│ ├── CMakeLists.txt
│ ├── include目錄
│ │ ├── myprint.h
│ ├── src 目錄
│ │ ├── myprint.cpp
│ ├── lib目錄
│ ├── biuld目錄
include目錄放置頭文件寥袭,src目錄下放置的是.c/.cpp源文件,biuld目錄是用來構(gòu)建的項(xiàng)目关霸,lib目錄用來放置我們生成庫文件传黄。
include目錄下的myprint.h頭文件
#include<stdio.h>
#include<stdlib.h>
void myprint(char* str);
src目錄下myprint.cpp文件
#include "/usr/demo/test5/include/myprint.h"
void myprint(char* str) {
printf("%s",str);
}
怎樣利用CMake來將項(xiàng)目編譯成動(dòng)態(tài)庫提供給其他項(xiàng)目使用。首先我們要?jiǎng)?chuàng)建CMakeLists.txt文件队寇,簡單的來說CMake就是我們把編譯信息錄入膘掰,cmake命令根據(jù)CMakeLists.txt生成編譯需要的Makefile文件〖亚玻看看CMakeLists.txt具體的編寫
#指定CMake編譯最低要求版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
#給項(xiàng)目命名
PROJECT(MYPRINT)
#收集c/c++文件并賦值給變量SRC_LIST_CPP ${PROJECT_SOURCE_DIR}代表區(qū)當(dāng)前項(xiàng)目錄
FILE(GLOB SRC_LIST_CPP ${PROJECT_SOURCE_DIR}/src/*.cpp)
FILE(GLOB SRC_LIST_C ${PROJECT_SOURCE_DIR}/src/*.c)
#指定頭文件目錄
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#指定生成庫文件的目錄
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
#去變量SRC_LIST_CPP 與SRC_LIST_C 指定生成libmyprint 動(dòng)態(tài)庫 默認(rèn)生成靜態(tài)庫 SHARED指定生成庫類型為動(dòng)態(tài)庫
ADD_LIBRARY(myprint SHARED ${SRC_LIST_CPP} ${SRC_LIST_C})
編寫好CMakeLists.txt文件 cd到項(xiàng)目biuld目錄執(zhí)行cmake命令 將會(huì)在biuld目錄下生成Makefile文件识埋,執(zhí)行make命令項(xiàng)目就會(huì)開始編譯,在項(xiàng)目lib目錄下生成libmyprint.so文件零渐,是不是非常簡單窒舟,相比編寫Makefile文件來說。生成的動(dòng)態(tài)庫文件那么我們?cè)趺慈ユ溄邮褂盟厮信危坷^續(xù)往下看
CMake鏈接使用庫文件
這里就不新建項(xiàng)目啦惠豺,直接在src目錄下新建源文件建hello.cpp 來應(yīng)用libmyprint.so庫。
#include <stdio.h>
#include "/usr/demo/test5/include/myprint.h"
int main() {
myprint("hello World\n");
return 0;
}
那么我們就要重新寫個(gè)CMakeLists.txt文件拦耐,內(nèi)容如下
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
#指定項(xiàng)目名稱
PROJECT(HELLO)
#將hello.cpp 賦值給SOURCE 變量
SET(SOURCE ${PROJECT_SOURCE_DIR}/src/hello.cpp)
#指定頭文件目錄
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#指定鏈接庫文件目錄
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
#將hello.cpp生成可執(zhí)行文件hello
ADD_EXECUTABLE(hello ${SOURCE})
#指定hello 鏈接庫myprint
TARGET_LINK_LIBRARIES(hello myprint)
cd到項(xiàng)目biuld目錄執(zhí)行cmake命令 將會(huì)在biuld目錄下生成Makefile文件耕腾,執(zhí)行make命令见剩,編譯完后杀糯,將在biuld目錄下生成可執(zhí)行文件hello。執(zhí)行helloAndroid程序員學(xué)習(xí)CMake最終還是要為我們Android項(xiàng)目服務(wù)苍苞,Android studio 2.2 之后開始采用 CMake 的這種方式來構(gòu)建NDK項(xiàng)目固翰。包括一些優(yōu)秀的開源庫也有采用CMake的方式來編譯。具體看看CMake在Android中的使用羹呵。
Android中的CMakeLists.txt
由于后面會(huì)寫一些關(guān)于NDK音視頻的知識(shí),就以引入FFmpeg音視頻庫來看看Android 中CMakeLists.txt是怎么編寫的骂际。
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# 需要引入我們頭文件,以這個(gè)配置的目錄為基準(zhǔn)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
#添加共享庫搜索路徑
link_directories(${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi)
# 指定源文件目錄
AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/main/cpp SRC_LIST)
add_library(
# Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# src/main/cpp/native-lib.cpp
${SRC_LIST}
)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
avcodec-57
avdevice-57
avfilter-6
avformat-57
avutil-55
swresample-2
swscale-4
postproc-54
# Links the target library to the log library
# included in the NDK.
${log-lib} )
總結(jié)
了解了CMake語法,以及它正真的意義冈欢。以后遇上Android NDK項(xiàng)目便可以自己編寫CMakeLists.txt文件內(nèi)容歉铝。要想更深的深入可以去學(xué)習(xí)一下CMake文檔。