CMake基础入门

news2024/11/24 20:40:37

文章目录

  • 一、一个目录下有一个源文件(入门)
    • 1.1 预定义的变量
    • 1.2 语法介绍
      • cmake_minimum_required
      • project
      • set
      • message
      • add_executable
    • 1.3 最基础的实例
    • 1.4 第一步优化:build目录
      • 实操流程
    • 1.5 第二步优化:src目录
      • 1.5.1 实操流程
      • 1.5.2 add_subdirectory
  • 二、一个目录下有多个源文件
    • 2.1 基础的实例
      • 2.1.1 项目结构和实例
      • 2.1.2 编译运行
    • 2.2 进阶优化
      • 2.2.1 项目结构和实例
      • 2.2.2 编译运行
      • 2.2.3 aux_source_directory
  • 三、多个目录有多个源文件
    • 3.1 基础的实例
      • 3.1.1 项目结构和实例
      • 3.1.2 编译运行
      • 3.1.3 include_directories
    • 3.2 进阶优化
      • 3.2.1 项目结构和实例
      • 3.2.2 编译运行
    • 3.3 进阶优化2
      • 3.3.1 项目结构和实例
      • 3.2.2 编译运行
  • 四、生成库(待更新)
    • DCMAKE_INSTALL_PREFIX
    • install

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程),能够输出各种各样的makefile或者project文件。可以理解为,编写Makefile难度太大,CMake基于Makefile做了二次开发。

安装CMake
我使用的是Ubuntu 22.04.2,在终端输入

sudo apt install cmake

完成之后,检查版本号,看是否安装成功

cmake -version

结果是

zxm@ubuntu:~$ cmake -version
cmake version 3.22.1

一、一个目录下有一个源文件(入门)

1.1 预定义的变量

  • CMAKE_CURRENT_LIST_DIR:CMakeLists 所在的路径
  • CMAKE_BINARY_DIR PROJECT_BINARY_DIR<projectname>_BINARY_DIR: 工程编译发生的目录。表示当前的构建目录,即执行 CMake 构建命令时所在的目录的路径。
  • CMAKE_SOURCE_DIRPROJECT_SOURCE_DIR<projectname>_BINARY_DIR: 工程顶层目录。表示包含项目名的最近一个 CMakeLists.txt 文件所在的目录的路径。
  • CMAKE_CURRENT_SOURCE_DIR:表示当前正在处理的 CMakeLists.txt 文件的所在目录的绝对路径。
  • CMAKE_C_COMPILER:指定 C 编译器
  • CMAKE_CXX_COMPILER:指定 C++ 编译器
  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径
  • LIBRARY_OUTPUT_PATH:库文件输出的存放路径
  • CMAKE_BUILD_TYPE: 构建的类型,例如 Debug(默认有-g) ,Release

1.2 语法介绍

cmake_minimum_required

用于指定 cmake 的最小版本要求。

cmake_minimum_required (VERSION 2.8)

project

通常作为 CMakeLists.txt 文件的第一条指令出现,用于定义项目的基本信息。通过设置属性,可以提供项目的名称、版本号、描述等信息,并指定项目所用的编程语言。

project(<project_name>
        [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [DESCRIPTION <project_description>]
        [HOMEPAGE_URL <homepage_url>]
        [LANGUAGES <language>...])

其中,<project_name> 是项目的名称,是 project 指令的必填参数。
<major>, <minor>,<patch>,<tweak> 可选地指定项目的版本号。

除了名称和版本号外,project 指令还支持设置其他可选属性:
-DESCRIPTION:可选地设置项目的描述信息。
HOMEPAGE_URL:可选地设置项目的主页 URL。
LANGUAGES:可选地指定项目使用的编程语言。默认情况表示支持所有语言。

set

用于创建新的变量,修改已存在的变量的值,以及删除变量。

set(<variable_name> <value> CACHE <type> <docstring> [FORCE])

其中:

  • <variable_name> 是要设置的变量名。
  • <value> 是要设置的变量的值。
  • CACHE 是一个可选的关键字,用于将变量设置为缓存变量,允许用户通过命令行或图形界面进行配置。
  • <type> 是变量的类型,可以是 STRING、BOOL、PATH 等。
  • <docstring> 是关于这个变量的描述文本,可选。
  • FORCE 是一个可选的关键字,用于强制覆盖之前定义的同名变量的值。

举个例子

// 设置了一个名为 SRC_FILES 的变量,其值为一组源文件的路径。
set(SRC_FILES src/main.cpp src/foo.cpp)
// 设置了一个名为 ENABLE_DEBUG 的缓存变量,其值为布尔类型,用于控制是否启用调试模式。
set(ENABLE_DEBUG TRUE CACHE BOOL "Enable debug mode")
// 设置了一个名为 MY_PATH 的缓存变量,其值为路径类型,指定了某个目录的路径。
set(MY_PATH "/path/to/something" CACHE PATH "Path to something")

message

用于在配置过程中打印一些特定信息,方便调试和打印状态。

message([<mode>] "message to display" ...)

其中,<mode> 是一个可选参数,用于指定消息的模式。常见的模式有以下几种:

  • STATUS:将消息以普通状态打印出来。
  • WARNING:将消息以警告的方式打印出来。
  • AUTHOR_WARNING:将消息以作者警告的方式打印出来。
  • SEND_ERROR:将消息以错误的方式打印出来,并停止配置过程。
  • FATAL_ERROR:将消息以致命错误的方式打印出来,并终止配置和构建过程。

add_executable

创建可执行文件目标,用于将一组源文件编译为可执行文件。

add_executable(<target_name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               source1 [source2 ...])

其中

  • <target_name> 是要创建的可执行文件的名称,可以自定义。
  • [WIN32] 和 [MACOSX_BUNDLE] 是可选的标志,用于指定平台特定的属性。
  • [EXCLUDE_FROM_ALL] 也是可选的标志,用于将目标从默认构建中排除。

举个例子

// 创建了一个名为 MyExecutable 的可执行文件目标,
// 并指定了三个源文件 main.cpp、foo.cpp 和 bar.cpp。
add_executable(MyExecutable main.cpp foo.cpp bar.cpp)

1.3 最基础的实例

1)创建两个文件main.cCMakeLists.txt
main.c里面编写

#include <stdio.h>

int main(){
    printf("This is CMake;\n");
    return 0;
}

CMakeLists.txt里面编写

# 单个目录的实现

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

# 工程项目的名称,注意不是执行文件名
project(Zxm)

# 手动加入文件 ${变量名},比如${SRC_LIST}
set(SRC_LIST main.c)

# message 和 echo 类型
message(STATUS "PROJECT_BINARY_DIR DIR " ${PROJECT_BINARY_DIR})
message(STATUS "PROJECT_SOURCE_DIR DIR " ${PROJECT_SOURCE_DIR})


# 创建可执行文件,名为hello
add_executable(hello ${SRC_LIST})  

2)在终端输入cmake ..表示当前目录
在这里插入图片描述
生成了下面几个文件
在这里插入图片描述

3)在终端输入make,生成可执行文件hello
在这里插入图片描述
在这里插入图片描述

3)执行./hello
在这里插入图片描述

4)如果还有一个main2.c,那么修改CMakeLists.txt,其他的一样

#单个目录的实现

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

# 工程项目的名称,注意不是执行文件名
project(Zxm)

# 手动加入文件 ${变量名},比如${SRC_LIST}
set(SRC_LIST main.c)
set(SRC_LIST2 main2.c)

# message 和 echo 类型
message(STATUS "PROJECT_BINARY_DIR DIR " ${PROJECT_BINARY_DIR})
message(STATUS "PROJECT_SOURCE_DIR DIR " ${PROJECT_SOURCE_DIR})


# 创建可执行文件,名为hello
add_executable(hello ${SRC_LIST})  
add_executable(hello2 ${SRC_LIST}) 

1.4 第一步优化:build目录

把很多生成的文件和源码混在一起,是一个很容易挨打的行为。我们可以单独创建一个子目录build,用来存放cmke后的结果。

实操流程

1)创建子目录build,进入到build

cd build/

2)终端输入cmake ..

# ..表示二级目录
cmake ..

3)终端输入make

这样就显得干净多了
在这里插入图片描述

1.5 第二步优化:src目录

为工程添加一个子目录src,用来放置工程源代码。结构如图
在这里插入图片描述

1.5.1 实操流程

1)创建子目录src,把main.c移到该目录下。并为任何子目录建立一个 CMakeLists.txt(跟工程1的一致)

#单个目录的实现

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

# 工程项目的名称,注意不是执行文件名
project(Zxm)

# 手动加入文件 ${变量名},比如${SRC_LIST}
set(SRC_LIST main.c)

# message 和 echo 类型
message(STATUS "PROJECT_BINARY_DIR DIR " ${PROJECT_BINARY_DIR})
message(STATUS "PROJECT_SOURCE_DIR DIR " ${PROJECT_SOURCE_DIR})
message(STATUS "CMAKE_CURRENT_SOURCE_DIR " ${CMAKE_CURRENT_SOURCE_DIR})

# 创建可执行文件,名为hello
add_executable(hello ${SRC_LIST})  

2)在主目录下,建立一个 CMakeLists.txt。主要点是add_subdirectory(src bin)

#单个目录的实现

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

# 工程项目的名称,注意不是执行文件名
project(Zxm)

# 手动加入文件 ${变量名},比如${SRC_LIST}
set(SRC_LIST main.c)

# message 和 echo 类型
message(STATUS "PROJECT_BINARY_DIR DIR " ${PROJECT_BINARY_DIR})
message(STATUS "PROJECT_SOURCE_DIR DIR " ${PROJECT_SOURCE_DIR})
# CMAKE_CURRENT_SOURCE_DIR它的CMakeLists.txt所在的当前源目
MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR " ${CMAKE_CURRENT_SOURCE_DIR})

# 添加子目录src,并将生成的二进制文件存放到 bin 目录中
add_subdirectory(src bin)

3)进入build目录,执行cmake ..make

cd build
cmake ..
make

在这里插入图片描述

注意到生成的可执行文件是存放到 bin 目录中,因此需要在bin目录下执行

cd bin
./hello

在这里插入图片描述

1.5.2 add_subdirectory

用于向 CMake 构建系统添加一个子目录。这个子目录可以包含另一个独立的 CMakeLists.txt 文件,用于管理子目录下的源码、库文件或其他构建内容。

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

其中:

  • source_dir:要添加为子目录的源码目录,需要包含一个独立的 CMakeLists.txt 文件。
  • binary_dir:可选参数,指定生成的二进制文件(如可执行文件、库文件)所存放的目录。如果不提供该参数,则默认为在当前构建目录生成二进制文件。
  • EXCLUDE_FROM_ALL:可选参数,表示将该子目录排除在默认构建(make 或 build)之外。

举个例子,假设我们的项目包含两个子目录,分别是 src 和 tests:

project/
├── CMakeLists.txt
├── src/
│   ├── CMakeLists.txt
│   └── ...
└── tests/
    ├── CMakeLists.txt
    └── ...

在主项目的 CMakeLists.txt 文件中,我们可以使用 add_subdirectory命令将这两个子目录添加进来:

add_subdirectory(src )
add_subdirectory(tests)

这样,在构建过程中,CMake 会先依次进入 src 目录和 tests 目录,执行这两个子目录下的 CMakeLists.txt 文件,分别进行对应的构建操作。

二、一个目录下有多个源文件

2.1 基础的实例

2.1.1 项目结构和实例

在这里插入图片描述

main.c编写

#include <stdio.h>

#include "testFunc.h"

int main(void)
{
	func(100);
	return 0;
}

testFunc.h编写

void func(int data);

testFunc.c编写

#include <stdio.h>
#include "testFunc.h"

void func(int data)
{
	printf("data is %d\n", data);
}

CMakeLists.txt编写(不加打印信息了)

cmake_minimum_required (VERSION 2.8)

project (zxm)

add_executable(hello main.c testFunc.c)

2.1.2 编译运行

进入build,运行查看

cd build/
cmake ..
make
./hello

在这里插入图片描述

2.2 进阶优化

如果源文件很多呢,几十个,一个个加入到add_executable就很麻烦。这时候可以使用aux_source_directory,用于自动将指定目录下的源文件列表添加到变量中。
并且,这么多源文件,最好放到单独的文件夹里面。

2.2.1 项目结构和实例

创建子目录src,存放源文件。在2.1例子的基础上,增加testFun1.c,testFun1.h文件,修改main.c文件。
在这里插入图片描述
testFun1.c编写

#include <stdio.h>
#include "testFunc1.h"

void func1(int data)
{
	printf("data is %d\n", data);
}

testFun1.h编写

void func1(int data);

main.c编写

#include <stdio.h>

#include "testFunc.h"
#include "testFunc1.h"

int main(void)
{
	func(100);
	func1(200);
	return 0;
}

src目录下的CMakeLists.txt编写

cmake_minimum_required (VERSION 2.8)

project (zxm)

# 把当前目录下的源文件添加到变量SRC_LIST中
aux_source_directory(. SRC_LIST)

add_executable(hello ${SRC_LIST})

主目录下的CMakeLists.txt编写

cmake_minimum_required (VERSION 2.8)

project (zxm)

add_subdirectory(src bin)

2.2.2 编译运行

cd build/
cmake ..
make
cd bin/
./hello

在这里插入图片描述

2.2.3 aux_source_directory

用于自动查找指定目录 dir 下的所有源文件,并将它们的完整路径(包括文件名)存储在变量 variable 中。

aux_source_directory(dir variable)

其中:

  • dir 是要进行源文件搜索的目录路径。
  • variable 是用于存储找到的源文件列表的变量名。

例如
假设有一个名为 src 的目录,其中包含以下源文件:main.cpp、helper.cpp 和 utils.cpp。你可以使用 aux_source_directory 命令来自动获取这些源文件:

# 搜索 src 目录下的所有源文件,并将它们的完整路径存储在变量 SOURCES 中。
aux_source_directory(src SOURCES)

然后,你可以使用 SOURCES 变量来指定要编译的源文件列表

add_executable(my_app ${SOURCES})

三、多个目录有多个源文件

3.1 基础的实例

3.1.1 项目结构和实例

.
├── build
├── CMakeLists.txt
└── src
    ├── CMakeLists.txt
    ├── main.c
    ├── test_func
    │   ├── testFunc.c
    │   └── testFunc.h
    └── test_func1
        ├── testFun1.c
        └── testFunc1.h

把testFunc.c和testFunc.h放在test_func目录下,把testFunc1.c和testFunc1.h放在test_func1目录下。

修改src目录下的CMakeLists.txt为
重点是include_directories,向工程添加多个特定的头文件搜索路径;相当于指定g++编译器的-I参数值。

cmake_minimum_required (VERSION 2.8)

project (zxm)

# 向工程添加多个指定头文件的搜索路径
include_directories(test_func test_func1)

# 把当前目录下的源文件添加到变量SRC_LIST中
aux_source_directory(test_func SRC_LIST)
aux_source_directory(test_func1 SRC_LIST1)

add_executable(hello main.c ${SRC_LIST} ${SRC_LIST1})

当然,也可以在main.c里包含具体的头文件路径,这就不需要include_directories

#include "test_func/testFunc.h"
#include "test_func1/testFunc1.h"

3.1.2 编译运行

cd build/
cmake ..
make
cd bin/
./hello

在这里插入图片描述

3.1.3 include_directories

用于向 CMake 构建系统添加一个或多个包含目录,告诉 CMake 在编译源代码时搜索头文件所在的目录。

include_directories(dir1 [dir2 ...])

其中,dir1、dir2 等是要添加的包含目录的路径。

例如,假设你的项目中有一个名为 include 的目录,里面包含了一些头文件。你可以使用 include_directories 命令将该目录添加到项目中:

include_directories(include)

3.2 进阶优化

综合上面介绍的,工程项目中,一般会把源文件放在src目录,头文件放在include目录,cmake生成的对象文件放在build目录,最终输出可执行文件放在build目录下的bin目录

3.2.1 项目结构和实例

.
├── build
├── CMakeLists.txt
├── include
│   ├── testFunc1.h
│   └── testFunc.h
└── src
    ├── CMakeLists.txt
    ├── main.c
    ├── testFunc1.c
    └── testFunc.c

修改src目录下的CMakeLists.txt

cmake_minimum_required (VERSION 2.8)

project (zxm)

# 向工程添加多个指定头文件的搜索路径
include_directories(../include)

# 把当前目录下的源文件添加到变量SRC_LIST中
aux_source_directory(. SRC_LIST)

add_executable(hello ${SRC_LIST})

3.2.2 编译运行

cd build/
cmake ..
make
cd bin/
./hello

在这里插入图片描述

3.3 进阶优化2

3.3.1 项目结构和实例

进一步,如果想修改可执行文件的生成路径,比如在src目录下的bin目录
在这里插入图片描述
修改src目录下的CMakeLists.txt

cmake_minimum_required (VERSION 2.8)

project (zxm)

# 向工程添加多个指定头文件的搜索路径
include_directories(../include)

# 把当前目录下的源文件添加到变量SRC_LIST中
aux_source_directory(. SRC_LIST)

add_executable(hello ${SRC_LIST})

# EXECUTABLE_OUTPUT_PATH 可执行文件输出的存放路径
# 包PROJECT_SOURCE_DIR 含项目名的最近一个 CMakeLists.txt 文件所在的目录的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

修改主目录下的CMakeLists.txt

cmake_minimum_required (VERSION 2.8)

project (zxm)

add_subdirectory(src)

3.2.2 编译运行

cd build/
cmake ..
make
cd ../src/bin/
./hello

四、生成库(待更新)

在软件开发中,动态库(Dynamic Library)和静态库(Static Library)是两种常见的库文件类型。

1) 动态库:

  • 动态库是一种在运行时加载的库文件。它以共享的方式被多个程序使用,可以在不同的应用程序之间共享代码和数据。
  • 动态库具有独立编译和链接的优势,因此可以以相对较小的体积提供功能模块。
  • 当一个程序调用动态库时,操作系统会在内存中加载该库,并将其映射到运行进程的地址空间。这种共享的方式可以节省系统资源和内存使用,并允许库的更新和升级。
  • 动态库的扩展名通常为 .so(在Linux/Unix)或 .dll(在Windows)。

2)静态库:

  • 静态库是一种在编译时链接到程序中的库文件。它会将库的代码和数据复制到最终生成的可执行文件中。
  • 静态库使得可执行文件完全自包含,不依赖于外部的库文件。这可以提供更好的可移植性和独立性,因为所有需要的代码都包含在一个文件中。
  • 静态库通常比动态库更容易部署和分发,因为不需要处理共享库的加载和依赖关系。
  • 静态库的扩展名通常为 .a(在Linux/Unix)或 .lib(在Windows)。

在实际开发中,可以根据项目需求和约束来选择使用动态库还是静态库。动态库适合用于提供公共功能的共享库,而静态库则适合用于构建独立、可移植的可执行文件。

DCMAKE_INSTALL_PREFIX

指定 camke install 时的相对路径前缀

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

install

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

install(TARGETS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])

目标文件的安装

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

参数中的TARGET可以是很多种目标文件,最常见的是通过ADD_EXECUTABLE或者ADD_LIBRARY定义的目标文件,即可执行二进制、动态库、静态库。

为了符合一般的默认安装路径,如果设置了DESTINATION参数,推荐配置在安装目录变量下的文件夹。
例如:

INSTALL(TARGETS myrun mylib mystaticlib
	   # 可执行二进制myrun安装到${CMAKE_INSTALL_BINDIR}目录
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
       # 可执行二进制myrun安装到${CMAKE_INSTALL_BINDIR}目录
       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
       # 可执行二进制myrun安装到${CMAKE_INSTALL_BINDIR}目录
       ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

普通文件的安装

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

FILES|PROGRAMS若为相对路径给出的文件名,将相对于当前源目录进行解释。其中,FILES为普通的文本文件,PROGRAMS指的是非目标文件的可执行程序(如脚本文件)。

# 将文本文件 myfile.txt 安装到目标路径的 share/myproject 目录下
install(FILES myfile.txt DESTINATION share/myproject)

目录的安装

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...]] [...])

该命令将一个或多个目录的内容安装到给定的目的地,目录结构被逐个复制到目标位置。

# 将目录 mydir/ 及其内容安装到目标路径的 include/myproject 目录下
install(DIRECTORY mydir/ DESTINATION include/myproject)

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

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

相关文章

用心做好一款堡垒机,升级版《新一代堡垒机建设指南》白皮书现已开放下载!

编者注&#xff1a;本文刊登在《新一代堡垒机建设指南》&#xff08;JumpServer v3.0发布纪念版&#xff09;序言部分&#xff0c;文章作者为JumpServer开源堡垒机项目创始人广宏伟。点击文章底部“阅读原文”链接&#xff0c;即可下载新版《新一代堡垒机建设指南》白皮书。 “…

Vue3 – 实现过渡动画

1 认识Vue的动画原理 2 动画中常见类的作用 3 animation动画实现 4 动画的常见属性设置 5 列表元素动画组实现 6 列表元素的移动动画 认识Vue的动画原理 利用transition标签和一系列的动画类来控制标签的动画效果。 transition标签的本质是帮你添加和删除动画类的。 trans…

SpringBoot整合EasyExcel实现读操作

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBoot整合EasyExcel实现读操作 ⏱️ 创作时间&#xff1a; 2023年…

linux中的sendmail发送邮件

Linux/UNIX 下的老牌邮件服务器。 Sendmail 作为一种免费的邮件服务器软件&#xff0c;已被广泛的应用于各种服务器中&#xff0c;它在稳定性、可移植性、及确保没有 bug 等方面具有一定的特色&#xff0c;且可以在网络中搜索到大量的使用资料。 一、邮件发送原理图 MUA&#x…

通过弹性算力支持与托管式机器学习服务,亚马逊云科技为客户提升技术竞争力

时下数字化浪潮中&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;已成为企业实现业务增长和数字化转型的重要技术&#xff0c;为企业提供了重新定义和调优业务模式的机遇。越来越多的企业希望利用人工智能技术提升竞争力&#xff0c;应对复杂的商业环境和市场挑战&…

机器学习实战:Python基于Ridge岭回归进行正则化(十三)

文章目录 1.前言1.1 岭回归的介绍1.2 岭回归的应用 2.自定义数据集实战演示2.1 导入函数2.2 创建数据集2.3 alpha0、1、10、100的分别情况 3.Dushanbe_house数据集实战演示3.1 导入函数和数据3.2 剔除空值及可视化3.3 整理数据3.4 训练和测试数据集3.5 评估数据集 4.讨论 1.前言…

mysql更新关联字段问题

现象 ### 表结构 CREATE TABLE wjf_test_update_num (id bigint(20) NOT NULL AUTO_INCREMENT,num1 int(11) DEFAULT NULL,num2 int(11) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8 |## 插入两行数据 insert into wjf_test_update_nu…

从源码理解Scala中函数reduceRight的计算过程

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 以List集合为例&#xff0c;进行reduceRight()的计算过程分析&#xff0c;总体分为两部分&#xff0c;一部分是看最顶层特质的那个通用的reduceRight方法&#xff0c;另一部分是讲直接混入的特质的…

【Linux】分布式存储系统 Ceph

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 分布式存储系统 Ceph Ceph 概述1、Ceph 简介2、存储基础3、Ceph 优势4、Ceph 架构4、Ceph 核心组件5、OSD 存储后端6、Ceph 数据的存储过程7、Ceph 版本发行生命周期 Ceph 集…

Day13 02-Linux常用命令汇总

文章目录 第三章 Linux的常用命令【重要】3.1 命令格式的说明3.2 帮助命令3.2.1 man3.2.2 help 3.3 文件处理命令3.3.1 cd3.3.2 ls3.3.3 pwd3.3.4 mkdir3.3.5 touch3.3.6 echo3.3.7 cp3.3.8 mv3.3.9 rm3.3.10 vi编辑器3.3.11 ln 3.4 查看命令3.4.1 cat3.4.2 more3.4.3 head3.4.…

代码量、代码行数计算工具

cloc 极客命令行工具 下载地址&#xff1a;https://github.com/AlDanial/cloc 常用命令&#xff1a; // 文件夹的名称 cloc ./StaticAnalyzer/计算结果&#xff1a; 速度快&#xff0c;结果精准&#xff0c;十分实用&#xff01;

51单片机学习--数码管显示

首先实现静态数码管显示 SMG表示共阴极 &#xff0c;要让第三位显示数字6&#xff0c;需要LED6端口接0&#xff0c;即Y50&#xff0c;5的二进制为101&#xff0c;按P2_4 到 P2_2 的顺序接&#xff0c;则CBA分别接101 然后在数码管另一端&#xff0c;需要点亮的接上1&#xff…

亚信科技荣任「DBL电信行业工作组」副组长单位,AntDB数据库连年入选《中国数据库产品图谱》

日前&#xff0c;“2023可信数据库发展大会”在京圆满召开。亚信科技凭借自研的电信级核心交易数据库AntDB在通信行业15年的技术积累和行业贡献&#xff0c;成功当选为数据库应用创新实验室&#xff08;DBL&#xff09;电信行业工作组副组长单位。AntDB数据库连续两年入选《全球…

客户案例 | 数字化加速,金融企业实现3D打印式应用程序开发

关键发现&#xff1a; 客户痛点&#xff1a;传统开发周期长&#xff0c;流程复杂&#xff0c;难以满足杭银消金在企业快速发展过程中的应用开发需求&#xff1b;内部业务因为优先级不高&#xff0c;导致开发资源分配有限&#xff0c;更加迟滞了管理部门数字化转型的进度。 解决…

大规模新能源并网下火电机组深度调峰优化调度

1主要内容 程序主要参考《大规模新能源并网下火电机组深度调峰优化调度》&#xff0c;建立了深度调峰基础模型&#xff0c;采用IEEE30节点系统&#xff0c;通过直流潮流建模&#xff0c;以火电机组运行成本、开机成本等综合运行成本最低为目标函数&#xff0c;包括潮流约束、旋…

Spring 能解决所有循环依赖吗?

以下内容基于 Spring6.0.4。 看了上篇文章的小伙伴&#xff0c;对于 Spring 解决循环依赖的思路应该有一个大致了解了&#xff0c;今天我们再来看一看&#xff0c;按照上篇文章介绍的思路&#xff0c;有哪些循环依赖 Spring 处理不了。 严格来说&#xff0c;其实也不是解决不了…

基于Python的汉字字频统计实验

完整资料进入【数字空间】查看——baidu搜索"writebug" 实验内容 针对不同语料统计汉字的字频&#xff0c;并进行比较。 实验要求和目的 给出前 100 个汉字高频字的频率统计结果&#xff1b; 分别给出前 1、20、100、600、2000、3000、6000 汉字的字频总和&…

makefile项目管理-规则和过程

目录 1、makefile基本规则 2、makefile执行过程 3、makefile的运行规则 1、makefile基本规则 &#xff08;1&#xff09;命名&#xff1a;makefile 和 Makefile &#xff08;2&#xff09;makefile文件&#xff1a;里面是多个命令的集合&#xff0c;使用make命令执行该文件 …

岩土工程安全监测振弦传感器的发展史

岩土工程安全监测振弦传感器的发展史 岩土工程安全监测是岩土工程学科领域的一个重要组成部分。随着科学技术的不断发展&#xff0c;传感器技术的应用也在不断地创新和完善。振弦传感器是一种重要的监测设备&#xff0c;其应用范围广泛&#xff0c;以其高灵敏度、高精度、长期…

Python实现HBA混合蝙蝠智能算法优化BP神经网络回归模型(BP神经网络回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝙蝠算法是2010年杨教授基于群体智能提出的启发式搜索算法&#xff0c;是一种搜索全局最优解的有效方法…