本文目标
- 使用
python
写一个管理cmake
工程的cli
程序
参考
Python CLI
python Click 官网
Click 中文文档
python多文件打包.exe执行文件
argparse 文档
使用说明
- 详细说明
思路
使用 click
制作单独的命令, 比如 mcmake_inti
,mcmake_built
, 每一个命令都打包为单独的可执行文件
然后用argparse
制作一个调度的可执行文件
一个 Hello World
文件列表
mcmake.py: 命令入口
mcmake_init.py: 初始化项目
mcmake_build.py: 构建
源码
mcmake_init.py
# -*- coding: utf-8 -*-import click@click.command()
@click.option('--init', help='初始化项目', nargs=0)
@click.option('--language', type=click.Choice(['c', 'c++']), prompt='选择语言', help='选择语言')
def init(init, language):click.echo('初始化项目')click.echo('language: %s' % language)if __name__ == '__main__':init()
mcmake_build.py
# -*- coding: utf-8 -*-import click@click.command()
@click.option('--build', help='初始化项目', nargs=0)
@click.option('--config', type=click.Choice(['debug', 'release']), default='debug', prompt='构建类型', help='构建类型')
def build(build, config):click.echo('初始化项目')click.echo('config: %s' % config)if __name__ == '__main__':build()
mcmake.py
# -*- coding: utf-8 -*-import argparse
import osparser = argparse.ArgumentParser()
parser.add_argument('init', help='初始化项目', nargs='?', const='1')
parser.add_argument('build', help='构建项目', nargs='?', const='2')
parser.add_argument('help', help='显示帮助', nargs='?', const='3')args = parser.parse_args()
if __name__ == '__main__':if 'init' == args.init:os.system('mcmake_init')elif 'build' == args.init:os.system('mcmake_build')elif 'help' == args.init:os.system('mcmake_init --help')os.system('mcmake_build --help')
打包
分别打包三个文件
# 打包 mcmake 调度命令
pyinstaller -F mcmake.py
pyinstaller mcmake.spec# 打包 mcmake 初始化命令
pyinstaller -F mcmake_init.py
pyinstaller mcmake_init.spec# 打包 mcmake_build 构建命令
pyinstaller -F mcmake_build.py
pyinstaller mcmake_build.spec
此时打包在了 ./dist
目录中
window验证
(venv) F:\2023\code\cmake\cm-cli\dist>dir驱动器 F 中的卷是 dox卷的序列号是 34D2-6BE8F:\2023\code\cmake\cm-cli\dist 的目录2023/01/23 02:55 <DIR> .
2023/01/23 02:55 <DIR> ..
2023/01/23 02:55 6,622,500 mcmake.exe
2023/01/23 02:46 6,903,074 mcmake_build.exe
2023/01/23 02:45 6,903,056 mcmake_init.exe3 个文件 20,428,630 字节2 个目录 92,017,352,704 可用字节(venv) F:\2023\code\cmake\cm-cli\dist>mcmake --help
usage: mcmake [-h] [init] [build] [help]positional arguments:init 初始化项目build 构建项目help 显示帮助options:-h, --help show this help message and exit(venv) F:\2023\code\cmake\cm-cli\dist>mcmake help
Usage: mcmake_init [OPTIONS]Options:--init TEXT... 初始化项目--language [c|c++] 选择语言--help Show this message and exit.
Usage: mcmake_build [OPTIONS]Options:--build TEXT... 初始化项目--config [debug|release] 构建类型--help Show this message and exit.(venv) F:\2023\code\cmake\cm-cli\dist>mcmake init
选择语言 (c, c++): c++
初始化项目
language: c++(venv) F:\2023\code\cmake\cm-cli\dist>mcmake build
构建类型 (debug, release) [debug]:
初始化项目
config: debug(venv) F:\2023\code\cmake\cm-cli\dist>mcmake_init
选择语言 (c, c++): c++
初始化项目
language: c++(venv) F:\2023\code\cmake\cm-cli\dist>mcmake_init --language=java
Usage: mcmake_init [OPTIONS]
Try 'mcmake_init --help' for help.Error: Invalid value for '--language': 'java' is not one of 'c', 'c++'.(venv) F:\2023\code\cmake\cm-cli\dist>mcmake_init --language=c++
初始化项目
language: c++(venv) F:\2023\code\cmake\cm-cli\dist>
然后把 dist
目录添加到环境变量再次验证
C:\Users\laolang>where mcmake
F:\2023\code\cmake\cm-cli\dist\mcmake.exeC:\Users\laolang>mcmake --help
usage: mcmake [-h] [init] [build] [help]positional arguments:init 初始化项目build 构建项目help 显示帮助options:-h, --help show this help message and exitC:\Users\laolang>mcmake init
选择语言 (c, c++): c++
初始化项目
language: c++C:\Users\laolang>
linux 验证
注意: linux 需要把可执行文件所在目录添加到
.bashrc
才可以
ubuntu@ubuntu-cpp:~$ mcmake --help
usage: mcmake [-h] [init] [build] [help]positional arguments:init 初始化项目build 构建项目help 显示帮助options:-h, --help show this help message and exit
ubuntu@ubuntu-cpp:~$ mcmake init
选择语言 (c, c++): c++
初始化项目
language: c++
ubuntu@ubuntu-cpp:~$ mcmake debug
ubuntu@ubuntu-cpp:~$ mcmake build
构建类型 (debug, release) [debug]:
初始化项目
config: debug
ubuntu@ubuntu-cpp:~$
正式开发前的准备
检查环境变量
上面的 Hello World
中调度命令为 mcmake
, 本来想设置成cm
的, 但是我的电脑上已经有了这个命令了
C:\Users\laolang>where cm
C:\Program Files\PlasticSCM5\client\cm.exeC:\Users\laolang>
解决办法就是把环境变量的顺序调整一下
功能点描述
要求
无侵入. 即便脱离 cm-cli
, 也不能影响cmake
工程的构建流程
命令是怎样用的
调度命令
选项 | 含义 |
---|---|
init | 初始化项目 |
build | 构建项目 |
run | 运行 |
test | 运行测试 |
doxygen | 生成 doxygen 文档 |
init 子命令
选项 | 含义 |
---|---|
--name | 项目名称 |
--language | 语言. 可选项: c, c++ |
--standard | 语言标准, 目前的标准: c(89,90,99,11,18) , c++(98,11,14,17,20,23). c语言默认为11, c++默认为14 |
--type | 项目类型. simple(单目录) , simple_app(多目录, 一个include, 一个src) , module_app(多目录, src和include下添加子目录. src 下每个子目录编译为静态库或动态库. 默认为动态库, 可单独配置) 默认为 simple_app |
--build-dir | 构建目录. 默认为 build |
--output-dir | 二进制或库文件输出目录. 默认为 bin |
build 子命令
选项 | 含义 |
---|---|
--type | 构建类型. debug 或 release . 默认为 debug |
目录结构
ubuntu@ubuntu-cpp:~/code/cmake/cm_test$ tree -a.
cm目录, 类似 .git 目录 ├── .cm
钩子脚本所在目录 │ ├── hooks
构建后运行的脚本 │ │ ├── post-build-sample.py
运行后运行的脚本 │ │ ├── post-run-sample.py
测试后运行的脚本 │ │ ├── post-test-sample.py
构建前运行的脚本 │ │ ├── pre-build-sampel.py
运行前运行的脚本 │ │ ├── pre-run-sample.py
测试前运行的脚本 │ │ └── pre-test-sample.py
日志 │ └── logs
顶层 CMakeLists.txt ├── CMakeLists.txt
doxygen 配置文件 ├── Doxyfile
二进制或库文件所在目录 ├── bin
构建目录 ├── build
cm 配置文件 ├── cm.json
doxygen 生成文档所在目录 ├── doc├── include
第三方库目录 ├── libs├── readme.md├── src
第三方库源码 └── third10 directories, 10 files
ubuntu@ubuntu-cpp:~/code/cmake/cm_test$
帮助文档
使用 VuePress 写出完整帮助文档
cmake 项目的准备
不考虑 32位
要求
- 要在windows上测试 mingw , tdm-gcc , msvc
- 要在 vscode 和 vs 分别测试
- linux也要测试
- cmake 脚本尽量简洁
simple
simple_app
module_app
上述操作有什么问题
- 调度命令有一个巨大的缺陷, 比如
cm init --language=c++
无法识别. 解决思路: 使用sys.argv
获取, 自己手动解析然后调用子命令 - 帮助文档的输出也是个问题, 理想的帮助文档应当是下面这样的.
解决思路很简单: 提前把帮助文档写在一个文本文件中, 然后读取这个本文文件再输出. 其实更高端点的做法是定制各个子命令的帮助文档F:\code>cm --help init 初始化--language 语言: java,c,c++--name 项目名称 build 构建--type 投建类型: debug, release--hlep 帮助 F:\code>
- 命令别名功能未实现, 目前好像也没啥实现的必要. 这个功能主要是将一些长命令缩短, 比如:
# 设置别名 cm config alias.msvc='cm build -g=Ninja type=Debug install_prefix=/install cxx_complier=/cl.exe make_program=ninja' # 使用 cm msvc
- 类似
git
一样, 区分全局配置与当前项目配置 - 需要添加语言标准检测. 简单来说, 就是提前准备好几个特定的程序, 针对不同的标准进行验证.
- 应当考虑第三方库
下一篇:
cmake 05 使用库