CMAKE使用记录

news2024/11/24 12:28:40

CMAKE使用记录

CMake简化了针对同一项目的不同平台、不同编译器的构建过程和编译过程,能够管理各种规模的项目。

CMAKE命令记录

cmake命令说明

语法:

# cmake构建项目的编译系统
Generate a Project Buildsystem
> cmake [<options>] -B <path-to-build> [-S <path-to-source>]
> cmake [<options>] <path-to-source | path-to-existing-build>

# cmake编译项目
Build a Project
> cmake --build <dir> [<options>] [-- <build-tool-options>]

# cmake安装项目的编译结果
Install a Project
> cmake --install <dir> [<options>]

# Open a Project
> cmake --open <dir>

# Run a Script
> cmake [-D <var>=<value>]... -P <cmake-script-file>

# Run a Command-Line Tool
> cmake -E <command> [<options>]

# Run the Find-Package Tool
> cmake --find-package [<options>]

# Run a Workflow Preset
> cmake --workflow [<options>]

# View Help
> cmake --help[-<topic>]

**cmake构建项目的编译系统**

cmake [<options>] -B <path-to-build> [-S <path-to-source>]
  - cmake3.13版本要求
  - <path-to-build>:指定build tree的目录
  - <path-to-source>:指定source tree的目录
  - 文件目录要求可以是绝对路径也可以是基于所在工作目录的相对路径
  - source tree的目录必须包含CMakeLists.txt文件
  - build tree的目录如果在命令运行前未创建,择自动会创建
# 例子
> cmake -S ./src -B ./build
cmake [<options>] <path-to-source>
  - 当前工作目录作为build tree的目录
  - <path-to-source>:指定source tree的目录
  - 文件目录要求可以是绝对路径也可以是基于所在工作目录的相对路径
  - source tree的目录必须包含CMakeLists.txt文件但是不能包含**CMakeCache.txt**文件,因为CMakeCache.txt是用来识别一个已经存在的build tree
# 例子:
> mkdir build ; cd build
> cmake ../src
cmake [<options>] <path-to-existing-build>
  - <path-to-build>:指定build tree的目录
  - 文件目录要求可以是绝对路径也可以是基于所在工作目录的相对路径
  - 指定build tree的目录必须包含**CMakeCache.txt**文件,才能保证cmake加载CMakeCache.txt指定的source tree

cmake构建项目的编译系统的命令行选项如下

# 指定需要cmake构建的项目根目录
> -S <path-to-source>
# 指定cmake为项目构建的编译系统目录
> -B <path-to-build>
# 创建或者更新一个CMake的cache入口,一般就是设定项目的一些自定义配置
> -D <var>:<type>=<value>, -D <var>=<value>
# 指定编译系统生成器
> -G <generator-name>
> 例子: cmake -G "Visual Studio 16 2019"
# 指定编译系统生成器的工具集
> -T <toolset-spec>
> 例子:cmake -G "Visual Studio 16 2019" -T "v141"
# 指定编译系统生成器的平台
> -A <platform-name>
> 例子:cmake -G "Visual Studio 16 2019" -A Win32
# 指定编译成果安装目录
> --install-prefix <directory>
# 指定日志输出级别
> --log-level=<level>

需要注意:

# 如果需要重新构建,需要删除构建目录下的所有内容,再用cmake构建
# 例子:
> rm -rf ./* 
> cmake ..

**cmake编译项目**

使用cmake构建出编译系统后,可以使用cmake本身命令编译项目,也可以使用原生工具集编译项目,例如Linux的make、windows的nmake。

cmake --build <dir>             [<options>] [-- <build-tool-options>]
cmake --build --preset <preset> [<options>] [-- <build-tool-options>]

cmake编译项目命令行选项:

--build <dir>
  指定项目编译目录。
-j [<jobs>], --parallel [<jobs>]
  指定用于编译的并发进程最大数量。如果<jobs>未指定,使用默认的数量。
  某些原生的编译工具总是并发来编译。可以将<jobs>设置为1,用来限制单个job来编译。
-v, --verbose
  表示打印详细编译过程
--clean-first
  编译之前先执行clean操作

**cmake安装项目**

编译完成项目后,可以使用cmake本身命令安装项目,也可以使用原生工具集安装项目,例如Linux的make、windows的nmake。

cmake --install <dir> [<options>]

cmake安装项目命令行选项:

--install <dir>
  指定编译成果所在目录。
--prefix <prefix>
  覆盖默认的安装目录前缀,CMAKE_INSTALL_PREFIX。
-v, --verbose
  表示打印详细安装过程

引用参考:
1.CMake官网


MESSAGE函数:

用于在CMakeLists.txt文件中记录日志消息

message([<mode>] “message text” …) # General messages
message(<checkState> “message text” …) # Reporting checks
message(CONFIGURE_LOG <text>…) # Configure Log

General messages:在日志中记录指定的消息文本。如果给出了多个消息字符串(message string),最终会连接成一条消息,且字符串之间没有分隔符。
可选的关键字确定消息的类型:

FATAL_ERROR:CMake Error,停止处理和生成
SEND_ERROR:CMake Error,继续处理,但跳过生成
WARNING:CMake Warning,继续处理
AUTHOR_WARNING:CMake Warning(dev),继续处理
DEPRECATION:如果分别启用了CMAKE_ERROR_DEPRECATED或CMAKE_WARN_DEPRECATED,则CMake弃用(Deprecation)Error或Warning,否则没有消息
(none)或NOTICE:重要的消息打印到stderr以引起用户的注意。
STATUS:project用户可能感兴趣的主要信息。理想情况下,这些信息应该简明扼要,不超过一行,但仍然信息丰富
VERBOSE:针对project用户的详细信息消息。这些消息应提供在大多数情况下不感兴趣的额外详细信息,但是在编译项目时可以提供更丰富的消息让用户明白编译发生的过程
DEBUG: 针对工作项目的开发者的详细信息消息
TRACE:低级的细粒度消息,使用此日志级别的消息通常只是临时的,一般在发布项目、打包文件之前被删除

CMake3.15版本开始才增加了NOTICE、VERBOSE、DEBUG、TRACE
--log-level=<level>命令行选项可用于控制显示哪些消息。若不指定,默认不会显示verbose, debug, trace消息。也可通过CMAKE_MESSAGE_LOG_LEVEL变量设置。有效日志级别如下:ERROR, WARNING, NOTICE, STATUS (default), VERBOSE, DEBUG, or TRACE

示例:

# 输出多条字符串组合
MESSAGE(“github addr:” “https://github.com/xxx”) # github addr:https://github.com/xxx
# 输出cmake预定义变量的值
MESSAGE(STATUS “Binary Dir:” ${DEMO_BINARY_DIR}) # Binary Dir: ~/Test


Reporting checks:CMake输出中的一个常见模式是一条消息表明某种检查的开始,然后是另一条消息报告检查的结果。这可以使用message命令的CHECK_…关键字形式可以更强大、更方便地表达这一点。其中必须是以下之一:

  • CHECK_START:记录关于将要执行的检查的简明信息
  • CHECK_PASS:记录检查的成功结果
  • CHECK_FAIL:记录检查的不成功结果。

INSTALL:

用于cmake在编译完成后安装
安装Targets

CMAKE_INSTALL_PREFIX: 指定安装目录的前缀路径
cmake --install时添加--prefix参数 会覆盖CMAKE_INSTALL_PREFIX指定的目录
> cmake --install . --prefix "/home/myuser/installdir"

install(TARGETS targets... [EXPORT <export-name>]
        [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET <set-name>]
        [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET <set-name>|CXX_MODULES_BMI]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [NAMELINK_COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
         [NAMELINK_ONLY|NAMELINK_SKIP]
        ] [...]
        [INCLUDES DESTINATION [<dir> ...]]
        )

参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的目标文件,可能是可执行二进制、动态库、静态库。

目标类型:ARCHIVE特指静态库或者windows的dll对应的lib导入库,LIBRARY特指动态库,RUNTIME特指可执行目标二进制。

DESTINATION定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX来定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是

${CMAKE_INSTALL_PREFIX}/<DESTINATION定义的路径>

CONFIGURATIONS为不同的编译配置设置安装规则(Debug, Release, 等等)。

install(TARGETS target
        CONFIGURATIONS Debug
        RUNTIME DESTINATION Debug/bin)
install(TARGETS target
        CONFIGURATIONS Release
        RUNTIME DESTINATION Release/bin)

PERMISSIONS 权限:

OWNER_WRITE,OWNER_READ,GROUP_READ和WORLD_READ组合:表示权限644

举例:

INSTALL(TARGETS myrun mylib mystaticlib
				RUNTIME DESTINATION bin
				LIBRARY DESTINATION lib
				ARCHIVE DESTINATION libstatic
				)

# 二进制myrun安装到${CMAKE_INSTALL_PREFIX}/bin目录
# 动态库lib mylib安装${CMAKE_INSTALL_PREFIX}/lib目录
# 静态库lib mystaticlib安装到${CMAKE_INSTALL_PREFIX}/libstatic目录
# 特别注意的是不需要关心TARGETS具体生成的路径,只需要写上TARGETS名称就可以了。

安装Files

CMAKE_INSTALL_PREFIX: 指定安装目录的前缀路径
cmake --install时添加--prefix参数 会覆盖CMAKE_INSTALL_PREFIX指定的目录
> cmake --install . --prefix "/home/myuser/installdir"

install(<FILES|PROGRAMS> files...
        TYPE <type> | DESTINATION <dir>
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])

安装Directories

CMAKE_INSTALL_PREFIX: 指定安装目录的前缀路径
cmake --install时添加--prefix参数 会覆盖CMAKE_INSTALL_PREFIX指定的目录
> cmake --install . --prefix "/home/myuser/installdir"

install(DIRECTORY dirs...
        TYPE <type> | DESTINATION <dir>
        [FILE_PERMISSIONS permissions...]
        [DIRECTORY_PERMISSIONS permissions...]
        [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>] [EXCLUDE_FROM_ALL]
        [FILES_MATCHING]
        [[PATTERN <pattern> | REGEX <regex>]
         [EXCLUDE] [PERMISSIONS permissions...]] [...])

DIRECTORY后面的参数是所在Source目录的相对路径,需要注意:
abc和abc/有很大的区别

  • 如果目录不以/结尾,那么这个目录将被安装到目标路径下的abc
  • 如果目录以/结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。

PATTERN用于使用正则表达式进行过滤,PERMISSIONS用于指定PATTERN过滤后的文件权限。

例子:

INSTALL(DIRECTORY icons scripts/ DESTINATION test/myproj
					PATTERN "CVS" EXCLUDE
					PATTERN "scripts/*"
					PERMISSIONS OWNER_EXECUTE OWNER_WRITE WONER_READ GROUP+EXECUTE GROUP_READ)

# 将icons目录安装到<prefix>/test/myproj,将scripts/中的内容安装到<prefix>/test/myproj
# 不包含名为CVS的目录
# 对于scripts/*文件指定权限为OWNER_EXECUTE OWNER_WRITE WONER_READ GROUP_EXECUTE GROUP_READ

安装时CMAKE脚本的执行

INSTALL([ [SCRIPT < file>] [ CODE < code >]] [...])
# SCRIPT参数用于在安装时调用cmake脚本文件(也就是<abc>.cmake文件)
# CODE参数用于执行CMAKE指令,必须以双引号括起来。比如:
INSTALL(CODE "MESSAGE(\"example install message.\")")


引用参考:
1.CMake官网
2.CMake中message的使用
3.cmake使用教程(实操版)


典型例子

hello cmake例子

提示:最简单的cmake使用例子:
新建文件夹hello,并进入hello文件夹,文件组织如下

hello
├── build/: CMake构建过程、编译过程的中间文件和结果文件保存目录(这样子可以确保不会污染项目源文件夹)
├── CMakeLists.txt: CMake构建配置文件
├── main.cc: 编译的源码
└── install/: 项目编译结果安装目录

main.cc:

#include <iostream>

int main() {
  std::cout << "hello cmake" << std::endl;
  return 0;
}

CMakeLists.txt:

PROJECT(HELLO)

MESSAGE(STATUS "Binary Dir:" ${HELLO_BINARY_DIR})
MESSAGE(STATUS "Source Dir:" ${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello main.cc)

构建过程:

#1. 切换到build目录
> cd ./build
#2. cmake构建
> cmake .. #..表示build的上级目录(即CMakeLists.txt所在的根目录)
#3. 编译(可直接使用cmake自带的编译命令,也可根据编译器选用特定的编译命令,比如Linux的make命令,windows的nmake命令)
#3.1 cmake自带的编译命令
> cmake --build . # .表示build当前目录
#3.2 make编译命令
> make .
#4. 安装(可直接使用cmake自带的安装命令,也可根据编译器选用特定的安装命令,比如Linux的make命令,windows的nmake命令)
> cmake --install . --prefix ../install

cmake .. 命令输出:
在这里插入图片描述
此时生成的编译系统及中间文件如下:
在这里插入图片描述
cmake --build . 命令输出:
在这里插入图片描述
此时编译成果如下:
在这里插入图片描述


例子中内容解释:

PROJECT(projectname [CXX] [C] [Java])

用这个语句定义工程名称,并且可以指定工程支持的语言,支持的语言列表是可以忽略的,默认情况表示支持所有语言。这个指令隐式的定义了两个cmake的变量:

<projectname>_BINARY_DIR:cmake构建的二进制目标目录
<projectname>_SOURCE_DIR:cmake构建项目的源目录
示例:见<cmake .. 命令输出:>截图
使用示例:${HELLO__BINARY_DIR}

这里需要注意:

使用 方式来取得变量中的值,如 {}方式来取得变量中的值,如 方式来取得变量中的值,如{HELLO__BINARY_DIR},而在IF语句中则直接使用变量名。


子目录 cmake例子

提示:子目录的cmake使用例子:
新建文件夹second,并进入second文件夹,文件组织如下

second
├── build/: CMake构建过程、编译过程的中间文件和结果文件保存目录(这样子可以确保不会污染项目源文件
├── CMakeLists.txt: CMake根目录构建配置文件
└── src/: 子目录
    ├── CMakeLists.txt: CMake子目录构建配置文件
    └── main.cc: 编译的源码

src/main.cc:

#include <iostream>

int main() {
  std::cout << "hello cmake" << std::endl;
  return 0;
}

src/CMakeLists.txt:

SET(SRC_LIST main.cc)
ADD_EXECUTABLE(hello ${SRC_LIST})

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
PROJECT(HELLO)

MESSAGE(STATUS "Binary Dir:" ${HELLO_BINARY_DIR})
MESSAGE(STATUS "Source Dir:" ${HELLO_SOURCE_DIR})

ADD_SUBDIRECTORY(src bin)

构建过程:

#1. 切换到build目录
> cd ./build
#2. cmake构建
> cmake .. #..表示build的上级目录(即CMakeLists.txt所在的根目录)
#3. 编译(可直接使用cmake自带的编译命令,也可根据编译器选用特定的编译命令,比如Linux的make命令,windows的nmake命令)
#3.1 cmake自带的编译命令
> cmake --build . # .表示build当前目录
#3.2 make编译命令
> make .

cmake .. 构建结果:
在这里插入图片描述

cmake --build . 编译结果:
在这里插入图片描述


例子中内容解释:

SET(SRC_LIST main.cc)

表示将源代码文件列表定义为一个变量,方便后续命令调用

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

这个命令用于向当前工程添加存放源文件的子目录。并可以指定中间二进制和目标二进制存放的位置。EXCLUDE_FROM_ALL参数的含义是将这个目录从编译过程中排除,比如,某个工程中的example,可能就需要工程构建编译完成后,再进入example目录单独进行构建编译(当然,你可以通过定义依赖来解决此类问题)。

本例子定义了将src子目录加入工程,并指定编译输出(包含编译中间结果)路径为bin目录。如果不进行bin目录的指定,那么编译结果(包括中间结果)都将存放在build/src目录(这个目录跟原来的src目录名字对应),指定bin目录后,相当于在编译时将src重命名为bin,所有的中间结果和目标二进制都存放在bin目录中。

可以通过SET指令重新定义EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量来指定最终的编译目标二进制的位置

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

85.最大矩形

单调栈&#xff0c;时间复杂度o(mn)&#xff0c;空间复杂度o(mn) class Solution { public:int maximalRectangle(vector<vector<char>>& matrix) {int mmatrix.size();if(m0){return 0;}int nmatrix[0].size();//记录矩阵中每个元素左边连续1的数量vector<…

如何开发一款高效便捷的搬家服务小程序

随着互联网的发展&#xff0c;小程序已成为各行各业重要的业务推广和用户服务平台。对于搬家行业而言&#xff0c;开发一款高效便捷的搬家服务小程序具有巨大的市场潜力。本文将为您详细介绍如何开发一款这样的搬家服务小程序。 一、进入乔拓云网后台 在开始制作搬家服务小程序…

番外项目---Vim编辑器

Task01: 1.在/tmp目录下建立一个名为mytest的目录&#xff0c;进入mytest目录当中; 2.将/etc/man_db.conf复制到上述目录下面&#xff0c;使用vim打开目录下的man_db.conf文件; 3.在vim中设定行号&#xff0c;移动到第58行&#xff0c;向右移动15个字符&#xff0c;请问你看到…

文件丢失怎么找回?收藏好这3个方法!

“我真的要哭了&#xff0c;不小心把一些很重要的文件弄丢了&#xff0c;现在不知道该怎么办了&#xff0c;有没有什么方法可以把这些文件找回来呀&#xff1f;大家快帮帮我吧&#xff01;” 在日常办公中&#xff0c;很多用户都会习惯性的把一些重要的文件和数据保存在电脑上。…

UE4游戏客户端开发进阶学习指南

前言 两年多前写过一篇入门指南&#xff0c;教大家在短时间内快速入门UE4的使用&#xff0c;在知乎被很多人收藏了。如今鸡佬使用UE快三年了&#xff0c;是时候更新一下进阶版本的学习指南。本文对于读者的要求&#xff1a; 有一定的C基础已经入门UE&#xff0c;能够用蓝图和…

AD 域控使用回收站批量还原用户

一、Read me. 测试版本winserver 2019&#xff0c;其余版本请查阅文档或者实际操作尝试。 前提需要预先开启回收站功能&#xff01;&#xff01;&#xff01;&#xff01; 没有开启可以点&#xff0c;开启后则变灰色。 如果是人为操作并且没有开启这个功能&#xff0c;那么不…

【算法训练-数组 四】【数组合并】:合并两个有序数组

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【数组组合】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

【小黑送书—第三期】>>《深入浅出SSD》

近年来国家大力支持半导体行业&#xff0c;鼓励自主创新&#xff0c;中国SSD技术和产业良性发展&#xff0c;产业链在不断完善&#xff0c;与国际厂商的差距逐渐缩小。但从行业发展趋势来看&#xff0c;SSD相关技术仍有大幅进步的空间&#xff0c;SSD相关技术也确实在不断前进。…

localhost和127.0.0.1都可以访问项目,但是本地的外网IP不能访问

使用localhost和127.0.0.1都可以访问接口&#xff0c;比如&#xff1a; http://localhost:8080/zhgl/login/login-fy-list或者 http://127.0.0.1:8080/zhgl/login/login-fy-list返回json {"_code":10000,"_msg":"Success","_data":…

数据结构与算法-循环链表、双向链表

我们这里接着上一篇单链表继续往下深入学习循环链表、双向链表。 链表 &#x1f388;3.循环链表&#x1f52d;3.1循环链表的概念&#x1f52d;3.2循环链表的基本操作&#x1f50e;3.2.1创建空表&#x1f50e;3.2.2插入操作&#x1f50e;3.2.3删除操作 &#x1f388;4.双向链表&…

图的存储-链式前向星

链式前向星 链式前向星是民间OI选手发明的数据结构。用另一个词解释它就是&#xff1a;用数组模拟的邻接链表。最核心的思想就是用数组模拟链表。 &#xff08;1&#xff09;前向星 前向星就是边的集合。一个图&#xff0c;只要将它的所有边存储起来&#xff0c;就能知道它的…

为什么append到父节点后的子节点发生修改,父节点打印出来的也会变化

今天走查前端代码&#xff0c;发现历史代码写出来的不规范&#xff0c;但是他还是在生产运行了很久的代码&#xff0c;仔细思量后发现&#xff0c;其实原理是对的&#xff0c;只是看起来不美观&#xff0c;不易读而已。 废话不说&#xff0c;先上demo代码 <!DOCTYPE html&g…

【Verilog 教程】7.1Verilog 除法器设计

除法器原理&#xff08;定点&#xff09; 和十进制除法类似&#xff0c;计算 27 除以 5 的过程如下所示&#xff1a; 除法运算过程如下&#xff1a; (1) 取被除数的高几位数据&#xff0c;位宽和除数相同&#xff08;实例中是 3bit 数据&#xff09;。 (2) 将被除数高位数据与…

实时选品系统实现的难点

实时选品系统是一个涉及到多个领域的复杂系统&#xff0c;需要兼顾数据挖掘和分析、推荐算法、机器学习、大数据处理等多方面的技术&#xff0c;才能实现高效、准确和可扩展的功能。 以下是实现实时选品系统时可能遇到的难点&#xff1a; 数据量大&#xff1a;实时选品系统需要…

无需公网IP,企业如何访问私有云?

企业的日常办公中已经习惯利用网盘或在线传输服务来进行文件传输和分享&#xff0c;面对一系列层出不穷的数据泄露和黑客行为&#xff0c;企业也越来越担心隐私泄露的问题&#xff0c;并寻找真正存储私有化的解决方案。某企业的总部在北京&#xff0c;在上海还有2处办公室&…

云服务器能干什么?腾讯云服务器的几十种玩法

腾讯云服务器价格很便宜尤其是轻量应用服务器&#xff0c;搞一台云服务器可以用来干嘛&#xff1f;云服务器的用途是很广的&#xff0c;现在轻量应用服务器2核2G3M、2核2G4M、4核8G12M等配置&#xff0c;百元的价格&#xff0c;买一台云服务器后可以做什么&#xff1f;拿来搭建…

PYTHON计算CPK及规范限合格率,绘制直方图概率密度曲线

CPK&#xff08;过程能力指数&#xff09;是一个用于衡量一个过程的稳定性和一致性的统计指标&#xff0c;特别用于制造业和质量管理中。它衡量了一个过程的变异性与规范界限的关系&#xff0c;帮助确定过程是否能够产生合格的产品或服务。 正态分布假设&#xff1a;CPK的计算…

多地智能停车场系统,如何实现数据互联互通?

某公司是从事嵌入式工控车牌自动识别系统、RFID蓝牙远距离读写系列、RFID电子标签系列、智能卡停车场、门禁一卡通智能管理系统、公务车派遣系统、运输车统计系统设备的开发、设计、制造、安装、调试及售后服务的企业。在智能卡停车场系统设备、人员通道闸设备方面有多项国家专…

通过Python脚本+Jekins实现项目重启

文章目录 一、需求二、分析三、实现公共代码单个服务版本1、写死某个服务2、支持服务单选 多服务版本最终实现效果将Python程序转换为桌面可执行文件&#xff08;.exe&#xff09; 一、需求 微服务项目&#xff0c;服务很多&#xff0c;重启服务&#xff0c;基本都是通过Jekin…

【微服务】RedisSearch 使用详解

目录 一、RedisJson介绍 1.1 RedisJson是什么 1.2 RedisJson特点 1.3 RedisJson使用场景 1.3.1 数据结构化存储 1.3.2 实时数据分析 1.3.3 事件存储和分析 1.3.4 文档存储和检索 二、当前使用中的问题 2.1 刚性数据库模式限制了敏捷性 2.2 基于磁盘的文档存储导致瓶…