Cmake笔记记录

工作后开发内容都是在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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT通过TCP协议发送结构体数据

文章目录 前言1. memcpy方式1.1 发送整个结构体1.2 发送部分数据 2. QDataStream2.1 符号<<2.2 wrieteRawData 总结 前言 做上位机的时候下发数据&#xff0c;数据是一个结构体&#xff0c;这里就阐述一下怎么通过TCP协议发送结构体。 我自己写的时候主要通过两种方式&a…

JavaWeb 速通HTTP

目录 一、HTTP快速入门 1.HTTP简介 : 2.HTTP请求头 : 3.HTTP响应头 : 二、HTTP响应状态码 1.基本介绍 : 2.常见状态码 : 3.状态码的分类 : 4.完整状态码汇总 : 三、HTTP请求包和响应包 1.请求包分析 : 1 GET请求 (1) 说明 (2) doGet返回数据给浏览器 (3) form表单提…

华为云CodeArts产品体验的心得体会及想法

文章目录 前言CodeArts 的产品优势一站式软件开发生产线研发安全Built-In华为多年研发实践能力及规范外溢高质高效敏捷交付 功能特性说明体验感受问题描述完结 前言 华为云作为一家全球领先的云计算服务提供商&#xff0c;致力于为企业和个人用户提供高效、安全、可靠的云服务。…

C++---树形DP---树的中心(每日一道算法2023.7.19)

注意事项&#xff1a; 本题为"树形DP—树的最长路径"的近似题&#xff0c;同时涉及到 单链表模拟邻接表存储图 的操作&#xff0c;建议先理解那篇文章。 题目&#xff1a; 给定一棵树&#xff0c;树中包含 n 个结点&#xff08;编号1~n&#xff09;和 n−1 条无向边…

uniapp查看ios打包后的Info.plist文件

最近在用 uni 开发 ios 的时候给项目添加了自定义的 Info.plist 文件&#xff0c;但是打包后发现并没有生效&#xff0c;才有了查看打包后的 Info.plist 文件想法。 HBuilderX3.6.5起&#xff0c;支持直接在应用项目中配置 iOS 平台的 Info.plist 和 资源文件&#xff08;Bundl…

C# List 详解二

目录 5.Clear() 6.Contains(T) 7.ConvertAll(Converter) ,toutput> 8.CopyTo(Int32, T[], Int32, Int32) 9.CopyTo(T[]) 10.CopyTo(T[], Int32) C# List 详解一 1.Add(T)&#xff0c;2.AddRange(IEnumerable)&#xff0c;3.AsReadOnly()&…

RabbitMQ集群搭建

说明&#xff1a;集群&#xff0c;不管是Redis集群&#xff0c;还是MQ集群&#xff0c;都是为了提高系统的可用性&#xff0c;使系统不至于因为Redis、MQ宕机而崩溃。本文介绍RabbitMQ集群搭建&#xff0c;RabbitMQ集群分为以下三类&#xff1a; 普通集群 镜像集群 仲裁队列 …

循环链表的实现

循环链表简介 简单来说&#xff0c;单链表像一个小巷&#xff0c;无论怎么样最终都能从一端走到另一端&#xff0c;循环链表则像一个有传送门的小巷&#xff0c;因为循环链表当你以为你走到结尾的时候&#xff0c;其实你又回到了开头。循环链表和非循环链表其实创建的过程以及…

程序员基础知识—IP地址

文章目录 一、什么是IP地址二、IP地址的分类三、子网掩码 一、什么是IP地址 IP地址就像我们需要打电话时的电话号码一样&#xff0c;它用来标识网络中的一台主机&#xff0c;每台主机至少有一个IP地址&#xff0c;而且这个IP地址是全网唯一的。IP地址由网路号和主机号两部分组…

Elasticsearch/Enterprise Search/Kibana安装记录

目录 Elasticsearch的安装导入 elasticsearch PGP密钥 安装使用APT安装手动下载安装 启动elasticsearch安全功能重新配置节点以加入现有集群启用系统索引的自动创建功能运行Elasticsearch(在systemd下)检查Elasticsearch是否正在运行Elasticsearch配置外网访问 第三方包安装ela…

Python学习(十六)柱状图

zdaPython学习&#xff08;十四&#xff09;折线图开发_yikuaidabin的博客-CSDN博客 案例数据资源 ↑ """演示基础柱状图的开发 """ from pyecharts.charts import Bar from pyecharts.options import LabelOpts # 使用Bar构建基础柱状图 bar …

【网络】socket——TCP网络通信 | 日志功能 | 守护进程

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 上篇文章中本喵介绍了UDP网络通信的socket代码&#xff0c;今天介绍TCP网络通信的socket代码。 TCP &a…

深度理解 Spring AOP

一、什么是AOP(面向切面编程)&#xff1f;&#x1f349; AOP 为 Aspect Oriented Programming 的缩写&#xff0c;意思为面向切面编程&#xff0c;是通过预编译方式 和运行期 动态代理 实现程序功能的统一维护的一种技术。 AOP &#xff08;面向切面编程&#xff09;是 OOP&a…

深度理解 Spring IOC

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

OJ练习第143题——二叉树展开为链表

二叉树展开为链表 力扣链接&#xff1a;114. 二叉树展开为链表 题目描述 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终…

postman批量执行请求,通过json传参

1、创建请求 "authUid":"{{authUid}}", 加粗为需要替换的参数 2、组装JSON 可通过Excel自动填充功能构造数据 [ {"authUid":"18700000001"}, {"authUid":"18725929202"} ] 3、批量执行请求配置 4、然后start r…

PuTTY连接服务器报错Connection refused

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Cloudreve搭建云盘系统,并实现随时访问

文章目录 1、前言2、本地网站搭建1.环境使用2.支持组件选择3.网页安装4.测试和使用5.问题解决 3、本地网页发布1.cpolar云端设置2.cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#xff0c;一时间公…

RabbitMQ惰性队列使用

说明&#xff1a;惰性队列是为了解决消息堆积问题&#xff0c;当生产者生产消息的速度远高于消费者消费消息的速度时&#xff0c;消息会大量的堆积在队列中&#xff0c;而队列中存放的消息数量是有限的&#xff0c;当超出数量时&#xff0c;会造成消息的丢失。而扩容队列&#…

uniapp app运行到ios详细流程

uniapp运行到IOS真机调试&#xff08;windows系统&#xff09; 工具步骤1.首先数据线连接电脑和手机2.右键点击桌面上的HBuilder&#xff0c;打开文件所在位置3.打开HBuilder编辑器里要运行的项目&#xff0c;点击运行>运行到手机或模拟器>运行到IOS APP基座>勾选你的…