Cmake笔记记录

news2024/11/24 12:56:56

工作后开发内容都是在Linux系统下完成,cmake使用比较频繁,找到一篇很不错的CMake笔记。
记录下来方便自己查阅。

目录

  • 1.CMake介绍
  • 2.示例一:编译单个文件
    • CMAKE_BUILD_TYPE
  • 3.示例二:编译同个目录下多个文件
    • aux_source_directory()
  • 4.示例三:编译多个目录下多个文件
    • add_subdirectory()
    • target_link_librarys()
    • add_library()
  • 5.示例四:通过CMake自定义编译选项
    • configure_file()
  • 6.示例五:CMake指定安装规则
  • 7.支持gdb
  • 8.添加环境检查
  • 9.添加版本号
  • 10.生成安装包
  • 11.导入第三方库
  • 12.链接本地库文件
  • 13.
  • 14.CMake 复制文件方法
    • FILE-COPY
    • ADD_CUSTOM_COMMAND
    • ADD_CUSTOM_TARGET
  • 15.关于CPack打包
  • 16.关于install的用法
  • 17.set_target_properties
  • 18.set_property
  • 19.CMAKE_PREFIX_PATH
  • 20.GLOB和GLOB_RECURSE

1.CMake介绍

CMake是一种跨平台的编译配置工具,它可以在不同的平台下基于同样的源代码文件生成对应的工程文件。例如Makefile和VS工程. 使用CMake的流程如下:
①编写CMakeLists.txt
②执行cmake PATH或ccmake PATH生成Makefile
③使用make进行编译

CMakeLists.txt的语法较为简单,由命令注释空格组成,其中命令是不区分大小写的,符号#后面的内容被认为是注释,命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。

2.示例一:编译单个文件

  • 工程目录如下
./Demo1
    |
    +--main.cpp

现在有一个源文件main.cpp,程序里面包含一个函数power,main中调用了它,在同目录下编写CMakeLists.txt文件。
在这里插入图片描述
main.cpp

#include <stdio.h>
#include <stdlib.h>

/**
 * power - Calculate the power of number.
 * @param base: Base value.
 * @param exponent: Exponent value.
 *
 * @return base raised to the power exponent.
 */
double power(double base, int exponent)
{
    int result = base;
    int i;

    if (exponent == 0) {
        return 1;
    }
    
    for(i = 1; i < exponent; ++i){
        result = result * base;
    }

    return result;
}

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    double result = power(base, exponent);
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

CMakeLists.txt

# CMake最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo1)

# 指定生成目标
add_executable(Demo main.cpp)

上面的CMakeLists.txt文件出现如下命令:

  • cmake_minimum_required:表示指定运行此配置文件所需的CMake的最低版本
  • project:参数值Demo1,表示此项目的名称是Demo1
  • add_executable:将名为main.cpp的文件编译成一个名为Demo的可执行文件

在当前目录执行cmake . cmake就会根据平台自动生成工程文件,未报错就继续执行make,生成可执行文件。
在这里插入图片描述

  • 运行可执行文件
    在这里插入图片描述
  • 指定DEBUG模式
    也可以在CMakeLists.txt文件中添加以下代码来指定DEBUG模式.
set(CMAKE_BUILD_TYPE Debug)

①修改CMakeLists.txt文件
在这里插入图片描述
②终端执行make clean
③将CMakeCache.txt文件删除,重新进行cmake .
在这里插入图片描述

CMAKE_BUILD_TYPE

1.可选值包括
Debug:用于在没有优化的情况下,使用带有调试符号构建库或可执行文件
Release:用于构建的优化的库或可执行文件,不包含调试符号
RelWithDebInfo:由于构建较少的优化库或可执行文件,包含调试符号MinSizeRel:用于不增加目标代码大小的优化方式,来构建或可执行文件

2.使用方法
set(CMAKE_BUILD_TYPE "Debug") # CMakeLists.txt中指定
或者
cmake .. -D CMAKE_BUILD_TYPE=“Debug” # 生成时命令行指定

3.示例二:编译同个目录下多个文件

  • 工程目录如下,把power函数单独写进一个MathFunctions.c的源文件中
./Demo2
    |
    +--main.cpp
    |
    +--MathFunctions.cpp
    |
    +--MathFunctions.h

在这里插入图片描述
main.cpp

#include <stdio.h>
#include <stdlib.h>
#include "MathFunctions.h"

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    double result = power(base, exponent);
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

MathFunctions.cpp

/**
 * power - Calculate the power of number.
 * @param base: Base value.
 * @param exponent: Exponent value.
 *
 * @return base raised to the power exponent.
 */
double power(double base, int exponent)
{
    int result = base;
    int i;

    if (exponent == 0) {
        return 1;
    }
    
    for(i = 1; i < exponent; ++i){
        result = result * base;
    }

    return result;
}

MathFunctions.h

#ifndef POWER_H
#define POWER_H

extern double power(double base, int exponent);

#endif

CMakeLists.txt

# CMake最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 指定生成目标
add_executable(Demo main.cpp MathFunctions.cpp)

此时CMakeLists.txt修改只是在add_executable命令中增加了一个MathFunctions.cc,如果源文件太多,可以使用aux_source_directory命令。

aux_source_directory()

该命令会查找指定目录下的所有源文件,然后把结果存进指定变量名,通过${variable}来使用变量。

aux_source_directory( <dir> <variable>)

修改CMakeLists.txt如下:

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 查找目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})

4.示例三:编译多个目录下多个文件

  • 工程目录如下,将MathFunctions.h和MathFunctions.cc文件移动到单独的Math目录下。
./Demo3
    |
    +--main.cpp
    |
    +--math/
            |
            +--MathFunctions.cpp
            |
            +--MathFunctions.h

需要在根目录和math下各建立一个CMakeLists.txt文件,先将math目录下的文件编译成静态库再由main函数调用。
只需要将示例二源码中main.cpp引用路径由#include "MathFunctions.h"改为#include "math/MathFunctions.h"即可。

根目录中的CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo3)

# 查找目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 添加 math 子目录
add_subdirectory(math)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})

# 添加链接库
target_link_libraries(Demo MathFunctions)

使用命令add_subdirectory指明项目包含一个子目录math,这样math目录下的CMakeList.txt 和源代码也会被处理。使用命令 target_link_librarys指明可执行文件main需要链接一个名为MathFunctions的链接库。

add_subdirectory()

target_link_librarys()

add_library()

子目录中的CMakeLists.txt

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)

# 指定生成 MathFunctions 链接库
add_library (MathFunctions ${DIR_LIB_SRCS})

使用命令add_library将src目录中的源文件编译为静态链接库

5.示例四:通过CMake自定义编译选项

CMake允许为项目增加编译选项,从而根据用户的环境和需求选择最合适的编译方案。

例如,可以把MathFunctions库设为一个可选的库,如果该选项为ON,就是用该库的数学函数来进行计算,否则就调用标准库中的数学函数库。

  • 工程目录如下
./Demo4
    |
    +--main.cpp
    |
    +--config.h.in
    |
    +--CMakeLists.txt
    |
    +--math/
            |
            +--MathFunctions.cpp
            |
            +--MathFunctions.h
            |
            +--CMakeLists.txt

在这里插入图片描述
①修改根目录下的CMakeLists.txt

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo4)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
	   "Use provided math implementation" ON)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

# 是否加入 MathFunctions 库
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  add_subdirectory (math)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunction)
endif (USE_MYMATH)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable (Demo ${DIR_SRCS})
target_link_libraries (Demo ${EXTRA_LIBS})
  • 其中configure_file命令用于加入一个配置文件config.h,这个文件由CMake从config.h.in生成,通过这样的机制,可以通过预定义一些参数和变量来控制代码的生成
  • option命令添加了一个USE_MYMATH选项,并且默认值是ON
  • if (USE_MYMATH)根据USE_MYMATH变量的值决定是否使用math目录下的MathFunctions库
  • option选项必须放置在coufibure_file 前,否则会按照没有定义USE_MYMATH来生成config.h

configure_file()

configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

复制一份输入文件到输出文件,替换输入文件中被@VAR@或者${VAR}引用的变量值。

configure_file的其他选项
COPYONLY:只拷贝文件,不进行任何的变量替换。这个选项在指定了NEWLINE_STYLE选项时不能使用(无效)。
ESCAPE_QUOTES:躲过任何的反斜杠(C风格)转义。
@ONLY:限制变量替换,让其只替换被@VAR@引用的变量(那么 ${VAR}格式的变量将不会被替换)。这在配置${VAR}语法的脚本时是非常有用的。
NEWLINE_STYLE style:指定输出文件中的新行格式。UNIX和LF的新行是\n,DOS和WIN32和CRLF的新行格式是\r\n。这个选项在指定了COPYONLY选项时不能使用(无效)。
通常情况下,输入文件以.h.in为后缀,输出文件以.h为后缀。
eg.

configure_file(src/translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) # f=复制src文件夹下的translations.qrc文件到编译的目录下

修改main.cpp文件
让其根据USE_MYMATH的预定义值来决定调用标准库还是MathFunctions库

#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#ifdef USE_MYMATH
  #include <MathFunctions.h>
#else
  #include <math.h>
#endif


int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }

    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);

#ifdef USE_MYMATH
    printf("Now we use our own Math library. \n");
    double result = power(base, exponent);
#else
    printf("Now we use the standard library. \n");
    double result = pow(base, exponent);
#endif
    
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

上面的程序引用了一个config.h,config.h控制是否定义了USE_MYMATH
config.h由config.h.in生成
config.h.in

#cmakedefine USE_MYMATH

我们要做的第一步是在顶层的CMakeLists.txt文件中添加该选项

CMake会自动根据CMakeLists配置文件中的设置生产config.h文件。
使用CMake进行编译即可得到使用MYMATH的编译版本,修改CMakeLists.txt中的USE_MYMATH为OFF即可使用库函数中的函数。

测试如下:
CMakeLists.txt中的USE_MYMATH为ON
在这里插入图片描述
使用cmake .后生成的config.h
在这里插入图片描述
运行结果:
在这里插入图片描述
CMakeLists.txt中的USE_MYMATH为OFF
在这里插入图片描述
使用cmake .后生成的config.h
在这里插入图片描述
运行结果:
在这里插入图片描述

6.示例五:CMake指定安装规则

CMake也可以指定安装规则,可以通过在产生Makefile后使用make install

首先在math/CMakeLists.txt的结尾添加下面两行:

# 指定 MathFunctions库的安装路径
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

上面的代码指明了MathFunctions库的安装路径,之后修改根目录的CMakeLists文件,在末尾添加下面几行:

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
        DESTINATION include)

通过上面的设置,生成的Demo文件和MathFunctions函数库。libMathFunctions.o将会被复制到/usr/local/bin中,而MathFunctions.h和生成的config.h文件将会被复制到/usr/local/include中。

PS:这里需要加权限sudo进行make install,否则会失败
在这里插入图片描述
cmake .
sudo make install
在这里插入图片描述

这里的/usr/local是默认安装目录,可以通过修改CMAKE_INSTALL_PREFIX变量的值来制定安装目录。

7.支持gdb

8.添加环境检查

9.添加版本号

10.生成安装包

11.导入第三方库

在CMake中导入第三方库可以通过include_directorieslink_directories设置第三方库的路径,然后使用target_link_libraries进行链接。

12.链接本地库文件

官方推荐使用find_library获得库绝对目录然后接target_link_libraries

find_library(VI_LIB vi ./vi/lib)
target_link_libraries(${PROJECT_NAME} ${VI_LIB})

13.

14.CMake 复制文件方法

http://t.zoukankan.com/JoyPoint-p-11629521.html

FILE-COPY

ADD_CUSTOM_COMMAND

ADD_CUSTOM_TARGET

15.关于CPack打包

https://blog.csdn.net/lqzer/article/details/125238748

16.关于install的用法

install用于指定在安装时运行的规则。它可以用来安装很多内容,可以包括目标二进制、动态库、静态库以及文件、目录、脚本等。

https://blog.csdn.net/qq_38410730/article/details/102837401

# 1.安装的文件夹
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/biz_sdk/lib/linux_lib/ DESTINATION lib)

# 2.安装的文件
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/config.json DESTINATION ./)

# 3.安装的动态链接库(库的软链接也会拷贝过去)
install(FILES ${PROJECT_SOURCE_DIR}/lib/libFormatConversion.so DESTINATION lib)

17.set_target_properties

set_target_properties(
Thirdlib
PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/libThirdlib.so
)

# 举例
set_target_properties(
MVS 
PROPERTIES IMPORTED_LOCATION 
${MVS_SOURCE_DIR}/lib/64/libMvCameraControl.so
)

18.set_property

https://blog.csdn.net/sinat_31608641/article/details/123834265

在指定域中设置一个命名属性

set_property(<GLOBAL                            |
                DIRECTORY [dir]                   |
                TARGET    [target1 [target2 ...]] |
                SOURCE    [src1 [src2 ...]]       |
                TEST      [test1 [test2 ...]]     |
                CACHE     [entry1 [entry2 ...]]>
               [APPEND][APPEND_STRING]
               PROPERTY <name>[value1 [value2 ...]])

在某个域中对零个或多个对象设置一个属性。第一个参数决定该属性设置所在的域。它必须为下面中的其中之一:

GLOBAL域是唯一的,并且不接特殊的任何名字。

DIRECTORY域默认为当前目录,但也可以用全路径或相对路径指定其他的目录(前提是该目录已经被CMake处理)。

TARGET域可命名零或多个已经存在的目标。

SOURCE域可命名零或多个源文件。注意:源文件属性只对在相同目录下的目标是可见的(CMakeLists.txt)。

TEST域可命名零或多个已存在的测试。

CACHE域必须命名零或多个已存在条目的cache.

必选项PROPERTY后面紧跟着要设置的属性的名字。其他的参数用于构建以分号隔开的列表形式的属性值。如果指定了APPEND选项,则指定的列表将会追加到任何已存在的属性值当中。如果指定了APPEND_STRING选项,则会将值作为字符串追加到任何已存在的属性值。

举例:

set_property(TARGET hikcamera_client PROPERTY POSITION_INDEPENDENT_CODE ON)

其中POSITION_INDEPENDENT_CODE ON表示编译成动态库。

19.CMAKE_PREFIX_PATH

https://www.cnblogs.com/Fitanium/p/16181605.html

20.GLOB和GLOB_RECURSE

file的一个作用是生成目录列表。

// 添加当前目录下的所有c文件列表到lib_srcs变量中
file(GLOB lib_srcs *.c)

// 添加当前目录及其子目录下的所有c文件列表到lib_srcs变量中
file(GLOB_RECURSE lib_srcs *.c)

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

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

相关文章

Kubernetes_核心组件_kubelet_kubelet服务全解析(二)

文章目录 前言kubelet 架构kubelet 职责Node管理(节点管理)Pod管理 kubelet管理Podkubelet如何管理当前节点上所有Podkubelet三个端口kubelet获取Pod清单kubelet通过CRI接口管理Pod以及里面的容器 PodWorker的工作细节PodWorker的工作细节PLEG组件PLEG报错 kubelet创建并启动Po…

uni-app 使用安卓模拟器 mumu教程

第一步 去官网下载 这个直接下载就行 第二步 去uni-app 里面配置 在这里设置adb路径和模拟器端口 进去安装目录找到adb.exe 相关的就行我的是 D:/moniqi/MuMuPlayer-12.0/shell/adb.exe 端口设置的是 16385 但是不起作用 第三步 .\adb connect 127.0.0.1:7555 .\adb devi…

可证明安全初步(Provable Security Basics)

Speecher: Bingsheng Zhang 这一系列的课程&#xff0c;为了介绍一些基础&#xff0c;弥补一些上密码学课和看论文的Gap。 历史上的密码学是art&#xff0c;就像鲁班锁&#xff0c;看着很精妙&#xff0c;但是没有证明。 1970s以来&#xff0c;逐渐发展成Science。 定义和模…

【未来趋势】无屏幕笔记本

近日&#xff0c;来自以色列的科技公司Sightful推出了号称全球首台增强现实&#xff08;AR&#xff09;笔记本电脑——Spacetop。通过AR技术&#xff0c;用户可以拥有一块100英寸的虚拟屏幕&#xff0c;并且可以无视环境在任何地点办公&#xff0c;如咖啡店、公园、飞机上等等&…

深度理解 Spring IOC

Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息&#xff0c;并在Spring容器中生成一份相应的Bean配置注册表&#xff0c;然后根据这张注册表实例化Bean&#xff0c;装配好Bean之间的依赖关系&#xff0c;为上层应用提供准备就绪的运行环境。 Bean缓存池&…

PHP8知识详解:PHP的历史版本

PHP&#xff08;全称&#xff1a;Hypertext Preprocessor&#xff09;是一种广泛应用于web开发的脚本语言。它最初由Rasmus Lerdorf在1994年开发&#xff0c;并于1995年发布了第一个版本。以下是PHP的一些历史大版本及其介绍&#xff1a; PHP 1.0&#xff08;1995年&#xff09…

因果图用例设计案例

大家在测试过程中经常用的等价类划分、边界值分析、场景法等&#xff0c;并不能覆盖所有的需求&#xff0c;下面就来讲一种不经常用到但又非常重要的测试用例编写方法-因果图法。 应用场景&#xff1a;页面上有多个控件&#xff08;输入&#xff09;&#xff0c;控件&#xff…

c++--反向迭代器的实现

1.反向迭代器 迭代器有两种&#xff0c;一种是正向的&#xff0c;一种是反向的&#xff0c;方向迭代器的主要功能就是实现数据的反向访问&#xff0c;通过正向迭代器的适配生成的&#xff0c;适配器就是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的…

Linux学习之Shell中if-else

在Shell脚本中&#xff0c;if-else使用方法如下&#xff1a; if [测试条件] then 测试条件成立执行 else条件不成立执行 ficat << CCC >> testIfElse.sh表示只有遇到CCC才结束往testIfElse.sh写入文件。<< CCC表示后续的输入作为子命令或者子Shell的输入&am…

[JavaScript游戏开发] 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示)

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 文章目录 系列文章目录前言一、本章节效果图二、介绍2.1、左边区域2.2、右边区域 三、列计划3.1、目标3.1.1、完成跟随人物二维动态地图绘制(本…

MySQL知识2

十、数据库表的6种约束 建表同时添加约束&#xff1a; 主键约束和唯一&#xff1a; 默认值&#xff1a; 检查约束&#xff1a; 未能生效&#xff0c;原因&#xff1a;版本是5.7 在8.0之后&#xff1a;支持检查约束 主键自增可以写null&#xff0c;可以写default&#xff0c;可以…

音视频开发-ffmpeg介绍-系列一

目录 一.简介 FFmpeg框架的基本组成包含: 二. FFmpeg框架梳理音视频的流程​编辑 基本概念&#xff1a; 三.ffmpeg、ffplay、ffprobe区别 4.1 ffmpeg是用于转码的应用程序 4.2 fffplay是用于播放的应用程序 4.3 ffprobe是用于查看文件格式的应用程序 4.4 ffmpeg是用于转…

LocalDateTime、OffsetDateTime、ZonedDateTime之间的关系

什么是LocalDateTime&#xff1f; ISO-8601日历系统中不带时区的日期时间。 该类不存储时区&#xff0c;所以适合日期的描述&#xff0c;比如用于生日、deadline等等。 但是如果没有偏移量/时区等附加信息&#xff0c;一个时间是不能表示时间线上的某一时刻的。 什么是Offset…

【网络编程】网络套接字udp通用服务器和客户端

1.预备知识 认识端口号 端口号(port)是传输层协议的内容&#xff1a; 端口号是一个2字节16位的整数(uint16)端口号用来标识主机上的一个进程IP地址port能够标识网络上的某一台主机和某一个进程一个端口号只能被一个进程占用 认识TCP协议 此处我们先对TCP(Transmission Con…

day34-Animated Countdown(动画倒计时)

50 天学习 50 个项目 - HTMLCSS and JavaScript day34-Animated Countdown&#xff08;动画倒计时&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport&q…

自动驾驶感知系统-超声波雷达

超声波雷达&#xff0c;是通过发射并接收40kHz的超声波&#xff0c;根据时间差算出障碍物距离。其测距精度是1~3cm.常见的超声波雷达有两种&#xff1a;第一种是安装在汽车前后保险杠上的&#xff0c;用于测量汽车前后障碍物的驻车雷达或倒车雷达&#xff0c;称为超声波驻车辅助…

易班开放应用授权重定向,出现跨域的解决方案

问题描述 今天开发H5网站需要接入易班&#xff0c;经过易班授权然后重定向&#xff08;code: 302&#xff09;&#xff0c;使用axios发请求&#xff0c;但是前后端均配置跨域的情况下&#xff0c;不管怎么弄都是一直跨域 但是我们看network&#xff0c;network中对应请求的res…

nvm安装(win/linux)

win安装nvm Win安装nvm1、下载nvm2、直接安装nvm-setup.exe3、cmd运行查看安装情况 Linux安装nvm1、下载nvm安装包2、安装及配置环境变量3、查看安装情况 前端开发多个工程&#xff0c;node版本需要时不时的进行切换&#xff0c;如果重新下载安装nodejs会导致浪费很多无用的时间…

人群异常聚集检测告警算法 yolov5

人群异常聚集检测报警系统基于yolov5图像识别和数据分析技术&#xff0c;人群异常聚集检测告警算法通过在关键区域布设监控摄像头&#xff0c;实时监测人员的密集程度和行为动态,分析和判断人群密集程度是否超过预设阈值&#xff0c;一旦发现异常聚集&#xff0c;将自动发出信号…