luckfollowme arm 学习篇(2) - cmake
之前我们使用 mingw64 中的 gcc 和 g++ 编译出来 exe 可执行文件
但是我们想要的是 android (linux) 的可执行文件 怎么办?
这时候就需要 ndk 中的 工具链了。
而 ndk 的工具链 常用的就是cmake 编译了
android studio sdk
安装过 android studio ,一开始会让你安装 SDK
</p>
</p>
在安装完 sdk 后, 该目录下有个 Sdk\platform-tools 文件夹
里面包含了 adb.exe sqlite3.exe 等工具 。 建议您把他放在 系统的环境变量下。
ndk
记得随带把 ndk 也安装上,这可以支持我们构建 android 的 二进制文件
ndk 全称应该叫 native develepment kit 本地开发工具包啥啥的吧。 反正它里面包含了支持我们开发
android native (c++) 代码的环境。
其中里面有个 build 目录
</p>
</p>
这里面包含了支持我们构建 ndk 项目的工具。
其中包含我们今天的主角 cmake。
Cmake
cmake 我也只是勉强会用的水平(ctril+c ctrl+v),概念啥的说不出来。
大致意思就是可方便我们跨平台编译的工具。
ndk 中包括了 cmake toolchain 工具链。
具体参考: https://developer.android.google.cn/ndk/guides/cmake?hl=zh-cn
一般来说 arm 是对于真机的。 其余就是电脑cpu的了,用于模拟器平板方面。
android 中 native 都是 elf 文件。
elf 类似 windows 的 PE。
大致有几个概念。
- 可执行文件 比如 exe文件 可以直接运行。
- 共享库 shared android 程序的话使用的话通过 System.loadLibrary() 加载在内存中,然后我们程序通过导出的符号引用中内存地址 来调用。
- 静态库 静态库会直接集成到我们的程序中,相当于 #include 把内存复制了一份打包到我们的程序中,会导致我们的的程序变大,但是运行速度更快。
关于 elf 我打算后续研究差不多在 讲一篇 xhook,目前 elf 对我来说还是有点困难。
cmake 安装
您可以在 msys2 中 输入
pacman -S mingw-w64-x86_64-cmake
进行安装
关于如何搜索包您可以在下面的地址进行搜索:
https://packages.msys2.org/search?t=binpkg&q=mingw-w64-x86_64-cmake
如果之前您是 通过 msys2 安装的 mingw-w64 并且已经放入了 msys2\mingw64\bin 在环境变量中,那么您输入 cmake --version 应该可以显示的出来
$ cmake --version
cmake version 3.26.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
CMakeLists.txt
CmakeLists.txt 是用来配置我们编译选项的。
里面有很多配置项,我其实都记不住。
我一般都是找些 用 cmake 搭建的 比较基础微小的 ndk 项目,然后把 cmake 配置 一步步搜索翻译一遍,哪里会有用就复制我的项目里面跑一下,加深下映像。
我也尝试用直接看官方文档,一步步看配置命令,但是脑袋不行,前一秒看了,后一秒就忘了。
在正式配置之前 , 您先下载 vscode 的cmake 插件 来为我们进行 inteiljSence
CMakeLists.txt 配置
首先我们将我们的项目结构改下:
由原来的:
-practice
hello.cpp
-practice
source
hello.cpp
说白了就是加个 source 目录
然后我们需要一个 CMakeLists.txt 文件
您可以像我一样先随便拿个模板复制我们第一章 practice 项目下。
我选的模板是 msys2\mingw64\share\cmake\Modules\FortranCInterface\CMakeLists.txt
因为我觉得它对于我们的项目来说够用了,再者 几乎安装过 cmake 的都有这个目录
当然,我们肯定是需要改改的。
您可以把 这个模板 复制项目的时候改成 CMakeLists-clone.txt 主要给我提供参考就行。
最终目录结构
-practice
source
hello.cpp
CMakeLists.txt
CMakeLists-clone.txt
我们把 CMakeLists.txt 按照 CMakeLists-clone.txt 内容改改
最终内容如下:
# 使用最小版本号
cmake_minimum_required(VERSION 3.5)
# 我们的项目名称
project(InlineHookPratice)
# 设置 c++ 和 c 的标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
# 查找的#include 头的位置
# 这样能给我们提示这个目录下的 头文件
include_directories(
./source/
)
# 设置我们要编译的资源 放入 SOURCE_CPP 变量里面
set(SOURCE_CPP
./source/hello.cpp
)
# 将我们要编译的资源 加入可执行文件 InlineHookPratice 里面 到时候编译出来就叫 InlineHookPratice.exe 或者 InlineHookPratice... 根据环境变化
add_executable(InlineHookPratice ${SOURCE_CPP})
Cmake build
接下来我们使用 mingw64 下的 cmake 构建cmake 项目
cmake -S. -B. # 构建cmake 项目 -S项目路径 -B构建路径 输入. 代表当前目录
cmake --build . # 根据cmake项目 构建 二进制文件
此时您应该会在当前目录下生成
InlineHookPratice.exe 文件
输入 ./InlineHookPratice.exe 也可以得到hello world 字样
当然如果我们可以更改 CMakeLists.txt 下面这条配置,用于构建 .dll .lib 的动态 静态库
add_executable(InlineHookPratice ${SOURCE_CPP})
这个后续在 NDK交叉编译 中我会谈及到