概念
你需要知道的资料
本文可以帮助你完成对Cmake的简单了解以及快速上手,更多功能以及更现代的用法请参见以下链接:
Introduction · Modern CMake (modern-cmake-cn.github.io)
GitHub - ttroy50/cmake-examples: Useful CMake Examples
CMake Tutorial — Mastering CMake
CMake Reference Documentation — CMake 3.30.4 Documentation
为什么是CMake
用途
make 存在以下问题,因此更高级的跨平台的编译配置工具CMake应运而生
-
make 不通用于 Windows(仅在Unix 类系统通用)。
-
make 要准确指明项目之间的依赖关系,在有头文件时难以处理。
-
语法过于简单,难以做复杂判断(不如shell/python)。
-
不同的编译器g++ MSVC clang有不同的 flag 规则,参数可能不通用。
CMake 只需要写一份 CMakeLists.txt,就能统一的描述所有平台的编译过程,不再需要为交叉编译多写makefile。够在调用时生成当前系统所支持的构建系统。
- 跨平台
- 简单的,统一的语句
跨平台
产生其他工具的脚本,再依据这个工具的构建方式使用
根据不同的平台、不同的编译器,产出各种不同的构建脚本
- 各种各样的makefile或者project文件。
- Android Studio利用CMake生成的是ninja。一个小型的关注速度的构建系统。我们不需要关心ninja的脚本,知道怎么配置CMake就可以了
本质是封装makefile 或 vcproj 或 ninja
整个编译链包括:
-
cmake,用于跨平台以及简化底层编译脚本的工具。
-
cmake生成更底层的编译命令
makefile(或build.ninja) 这一过程一般不直接参与
-
比如 make解析.makefile文件进行命令执行,
-
比如 ninja 解析 .ninja文件进行命令执行(编译速度比makefile更快)。
-
-
C/C++语言的编译器(clang/gcc g++/cl/MSVC等等)。
简单的option
CMake 可以自动检测当前的编译器,需要添加哪些 flag。
比如 OpenMP,只需要在 CMakeLists.txt 中指明 target_link_libraries(a.out OpenMP::OpenMP_CXX) 即可。
CMake options:cmake运行时可以加入的命令行参数
-
比如 -D来定义对应的变量控制对应的cmake行为,甚至于前面的Build type我们完全可以不写(当然这是CLion,这个空必须得被填充),
-
-DCMAKE_BUILD_TYPE=Release,这个变量可以决定最终cmake生成的执行脚本是按照release的标准去运行的,
-
-DBUILD_SHARED_LIBS=ON,那么最终是会生成动态库而不是静态库。
广受欢迎
在Android Studio 2.2及以上,构建原生库的默认工具是CMake。Clion也使用CMake构建项目。
Lion如何编译项目生成可执行文件:
-
通过cmake配置选项运行整个项目的CMakeList.txt
-
生成makefile或其他底层脚本
-
通过对应的工具去执行这个脚本
-
运行编译好的程序
以Android Studio为例
之前使用
Android.mk
使用eclipse
构建新的库。
-
app/libs
下放置fmod.jar
Activity销毁后,jar包会做回收工作
fmodstudioapi11009android\api\lowlevel\lib\fmod.jar
-
app/src/main/cpp
放置inc
fmodstudioapi11009android\api\lowlevel\inc
-
创建
app/src/main/jniLibs
放置arm64-v8a
armeabi-v7a
armeabi
x86
fmodstudioapi11009android\api\lowlevel\lib
之下的arm64-v8a
(最新,指令集效率更高)armeabi-v7a
armeabi
(最老,被其他兼容)x86
MainActivity.java
import com.derry.as_jni_2_02.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
// 最终目标让 libfmod_learning01.so 动态库 libfmod_learning01.a 静态库
static {
// 加载 apk/lib/平台/lib项目名.so 库 (此库里面有 项目名.cpp 等代码)
// 需要使用Fmod,就需要让 lib项目名.so 包含Fmod, 通过CMake集成
System.loadLibrary("fmod_learning01"); // System.loadLibrary("项目名");
}
so
:linux Android的动态链接库
包 package
包 (package) 库的集合
-
现代 CMake 认为一个 包 (package) 可以提供多个 库,库又称组件 (components)。比如 TBB 这个包,就包含了 tbb, tbbmalloc, tbbmalloc_proxy 这三个组件。
-
原因
-
为避免冲突,每个包都享有一个独立的名字空间,以 :: 的分割(和 C++ 还挺像的)。
-
可以指定要使用包中的哪几个库(组件)
-
库
-
库中的函数可以被可执行文件调用,也可以被其他库文件调用。
-
若多个可执行文件,他们之间用到的某些相同的功能。就可以把共用的功能做成一个库,进行共享。
-
根据平台&种类 进行分类
-
dll
: windows的动态链接库 -
dawenlib
: Mac -
so
:linux Android的动态链接库
-