CMake基础
文章目录
一、常用命令
1. cmake最低版本
cmake_minimum_required(VERSION 3.10.2)
2. 指定项目
project(soundTouch)
3. 设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libs/${ANDROID_ABI})
4. 生成可执行文件 main
add_executable(main main.c)
5. 将一个CMAKE变量设置为给定值
set(DIR_SRCS ${PROJECT_SOURCE_DIR}/jni/include)
set(SRC_LIST main.cc util.cc train.cc)
6. 查找当前目录所有源文件 并将名称保存到 DIR_SRCS 变量
但不能查找子目录
aux_source_directory(. DIR_SRCS)
7. 为了确保 CMake 可以在编译时定位头文件
include_directories( imported-lib/include/ )
8. 指定编译为静态库
add_library (child STATIC
other.cpp # 支持多文件
${DIR_SRCS})
9. 指定编译为动态库
add_library (child SHARED
other.cpp
${DIR_SRCS})
10.NDK中已经有一部分预构建库 ndk库已经是被配置为cmake搜索路径的一部分
findLibrary(log-lib log)
target_link_libraries( native-lib
${log-lib} )
11. 使用 IMPORTED 标志告知 CMake 只希望将库导入到项目中
如果是静态库则将shared改为static
add_library( imported-lib
SHARED
IMPORTED )
12. 参数分别为:库、属性、导入地址、so所在地址
set_target_properties( avutil
PROPERTIES
IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavutil.so )
二、CMake 常用变量
- CMAKE_BINARY_DIR、PROJECT_BINARY_DIR、_BINARY_DIR:指的是工程编译发生的目录
- CMAKE_SOURCE_DIR、PROJECT_SOURCE_DIR、_SOURCE_DIR: 指的是工程顶层目录
- CMAKE_CURRENT_SOURCE_DIR: 指的是当前处理的CMakeLists.txt所在路径
- CMAKE_CURRENT_BINARY_DIR: 指的是工程编译结果存放的目标目录,可以通过set命令或ADD_SUBDIRECTORY(src bin)改变这个变量的值,但是set(EXECUTABLE_OUTPUT_PATH <new_paht>)并不改变这个变量的值,只会影响最终的保存路径
- CMAKE_CURRENT_LSIT_FILE: 指的是当前CMakeLists.txt文件所在完整路径
- CMAKE_CURRENT_LSIT_LINE: 指的是调用这个变量当前所在行(在MakeLists.txt中的行数)
- CMAKE_MODULE_PATH: 指的是自己加入的cmake模块路径,通过set来设置
- EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH:定义最终编译结果的二进制执行文件和库文件的存放目录
- PROJECT_NAME: 指的是通过set设置的PROJECT的名称
- ENV{NAME}: 指的是环境变量,通过set(ENV{NAME} new_path)设置,通过$ENV{NAME}调用
- CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH:这两个是系统变量而不是cmake变量,需要在bash中用export或在csh中用set命令设置
- CMAKE_MAJOR_VERSION: CMAKE主版本号,比如 2.4.6 中的2
- CMAKE_MINOR_VERSION: CMAKE次版本号,比如 2.4.6 中的4
- CMAKE_PATCH_VERSION: CMAKE补丁等级,比如 2.4.6 中的6
- CMAKE_SYSTEM:系统名称,比如 Linux-2.6.22
- CMAKE_SYSTEM_NAME: 不包含版本的系统名,比如 Linux
- CMAKE_SYSTEM_VERSION: 系统版本,比如 2.6.22
- CMAKE_SYSTEM_PROCESSOR: 处理器名称,比如 i686.
- UNIX: 在所有的类UNIX平台为 TRUE,包括 OS X 和 cygwin
- WIN32:在所有的win32平台为 TRUE,包括 cygwin
示例
# 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 需要的最低版本
cmake_minimum_required(VERSION 3.10.2)
# Declares and names the project.
project("android_ffmpeg")
#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libs/${ANDROID_ABI})
# 1. 定义so库和头文件所在目录,方面后面使用
set(ffmpeg_lib_dir ${PROJECT_SOURCE_DIR}/../libs/${ANDROID_ABI})
##当前../jni目录的所有.c .cpp源文件,并且赋值到SRC_LIST
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/jni/include SRC_LIST)
# 2. 添加头文件目录
include_directories(${PROJECT_SOURCE_DIR}/jni/include)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
# 3. 添加ffmpeg相关的so库
#创建和命名该库,第一个参数是库的名字,例如取名为 native-lib,将会生成一个命名为 libnative-lib.so 的库。
# 第二个参数是指定库的类型,一般为 SHARED,即动态库(以 .so 为后缀),还有一种是静态库 STATIC,即静态库(以 .a 为后缀)。
# 第三个参数是指定该库使用的源文件路径。
# 使用多个 add_library() 命令,您可以为 CMake 定义要从其他源文件构建的更多库。
# set_target_properties 设置输出别名,所以,希望 "hello_static" 在输出时,不是"hello_static",而是以"hello"的名字显示,故设置如下
add_library( avutil
SHARED
IMPORTED )
set_target_properties( avutil
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavutil.so )
add_library( swresample
SHARED
IMPORTED )
set_target_properties( swresample
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libswresample.so )
add_library( avcodec
SHARED
IMPORTED )
set_target_properties( avcodec
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavcodec.so )
add_library( avfilter
SHARED
IMPORTED)
set_target_properties( avfilter
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavfilter.so )
add_library( swscale
SHARED
IMPORTED)
set_target_properties( swscale
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libswscale.so )
add_library( avformat
SHARED
IMPORTED)
set_target_properties( avformat
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavformat.so )
add_library( postproc
SHARED
IMPORTED)
set_target_properties( postproc
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libpostproc.so )
add_library( avdevice
SHARED
IMPORTED)
set_target_properties( avdevice
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavdevice.so )
# 配置目标so库编译信息
add_library( # Sets the name of the library.
ffmpeg_lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${PROJECT_SOURCE_DIR}/jni/ffmpeg-lib.cpp
)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
# 找到一个 NDK 的库,并且将这个库的路径存储在一个变量中。例如上例中是找到 NDK 中的 log 库(Android 特定的日志支持库),
# 并将其路径存储在 “log-lib” 变量中,在后面你就可以通过 “${log-lib}” 命令取出变量中的值了。
# 查找代码中使用到的系统库
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 )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
# 关联库。将指定的库关联起来 。
# 指定库的库应该链接到你的目标库。您可以链接多个库,比如在这个构建脚本中定义的库、预构建的第三方库或系统库。
target_link_libraries( # Specifies the target library.
ffmpeg_lib
# 4. 连接 FFmpeg 相关的库
avutil
swresample
avcodec
avfilter
swscale
avformat
postproc
avdevice
# Links the target library to the log library
# included in the NDK.
${log-lib} )
# 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.10.2)
# Declares and names the project.
project("soundTouch")
#// ${PROJECT_SOURCE_DIR} 实际当前module 但是有些AS 会有问题
#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libs/${ANDROID_ABI})
##当前../jni目录的所有.c .cpp源文件,并且赋值到SRC_LIST
AUX_SOURCE_DIRECTORY(soundtouch SRC_LIST)
# 2. 添加头文件目录
include_directories(soundtouch)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_definitions(-DDEBUG)
add_library( # Sets the name of the library.
soundTouch
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
soundtouch-jni.cpp
${SRC_LIST})
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
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 )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
soundTouch
# Links the target library to the log library
# included in the NDK.
${log-lib} )