现代CMake

文章目录

  • 现代CMake
    • -D选项:指定配置变量
    • -G生成选项
    • 添加cpp源文件
    • 项目配置变量
      • 设置构建方式
        • 各种构建模式在编译器上的区别
      • project
        • 其他相关变量
        • project初始化:LANGUAGES 字段
        • project初始化:VERSION字段
        • project 内的其他字段
      • 设置C++标准
        • 常见误区
    • 链接库文件
      • 常见坑点:
    • CMAKE中对象的属性
    • 链接第三方库
    • 输出和变量
    • 变量和缓存
      • 缓存变量类型
    • 跨平台和编译器
    • 分支与判断
    • 变量的作用域
      • 子模块如何向父模块传递变量
    • 其他
    • 一个CMakeList.txt模板

现代CMake

如果你一点基础都没有, 请先看上一篇 CMAKE学习

  • cmake 3.x 是现代cmake

早先cmake编译命令如下

mkdir -p build
cd build
cmake ..
make -j4
make install 
cd ..

现代cmake编译命令如下

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel 4
cmake --build build --target install 

-D选项:指定配置变量

-DCMAKE_INSTALL_PREFIX=/opt/test

-DCMAKE_BUILD_TYPE=Release

-G生成选项

性能上Ninja > Makefile > MSBuild

添加cpp源文件

# 第一种
add_executeable(main main.cpp other.cpp)
# 第二种
add_executeable(main)
target_sources(main PUBLIC main.cpp other.cpp)
# 第三种
add_executeable(main)
set(sources main.cpp other.cpp)
target_sources(main PUBLIC ${sources})
# 第四种 批量获取,这种需要重新更新 CONFIGURE_DEPENDS 属性会检测是否添加了新的文件,如果检测到会刷新sources值,否则不会自动刷新
add_executeable(main)
file(GLOB sources CONFIGURE_DEPENDS /path/*.cpp)
target_sources(main PUBLIC ${sources})
# 如果有其他文件夹,除了按照上面的方式指定文件夹,还可以用下面的方式
add_executeable(main)
aux_source_dirctory(. sources)
aux_source_dirctory(mylib sources)
file(GLOB sources CONFIGURE_DEPENDS *.cpp)
target_sources(main PUBLIC ${sources})
# 如果有子文件夹,除了按照上面的方式指定文件夹,还可以用下面的方式 GLOB_RECURSE会递归当前文件夹和对应的子文件夹,注意这种会递归当前文件夹下的所有文件夹哦
add_executeable(main)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS /path/*.cpp)
target_sources(main PUBLIC ${sources})

项目配置变量

设置构建方式

CMAKE_BUILD_TYPE

# Debug Release MinSizeRel RelWithDebInfo 默认情况下是空,相当于Debug
set(CMAKE_BUILD_TYPE Release) 
各种构建模式在编译器上的区别
  • Debug: ‘-O0 -g’
  • Release: ‘-O3 -DNDEBUG’
  • MinSizeRel: ‘-Os -DNDEBUG’
  • RelWithDebInfo: ‘-O2 -g -DNDEBUG’

注意定义了NDEBUG宏会使assert被去除掉

project

cmake_minimum_required(VERASION 3.8)
project(hellocmake)
message("PROJECT_NAME: ${PROJECT_NAME}")
message("PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message("PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
message("CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
message("CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}")
add_executeable(main main.cpp)
  • PROJECT_NAME: 项目名称,比如对于msvc会生成一个hellocmake的sln文件

  • CMAKE_CURRENT_SOURCE_DIR: 表示当前CMakeList.txt源码目录位置

  • CMAKE_CURRENT_BINARY_DIR: 表示当前输出目录位置

  • PROJECT_SOURCE_DIR:表示最近调用project的CMakeList.txt所在的源码目录

  • CMAKE_SOURCE_DIR:表示最外层CMakeLists所在源码目录

不建议使用CMAKE_SOURCE_DIR,那样会让你的项目无法被别人作为子项目使用

其他相关变量
  • PROJECT_BINARY_DIR:当前项目输出路径
  • CMAKE_BINARY_DIR:根项目输出路径
  • PROJECT_IS_TOP_LEVEL:BOOL类型,表示是否是根项目
  • CMAKE_PROJECT_NAME:根项目名称

子模块可以使用project命令,将当前目录作为一个独立的子项目,这样的话PROJECT_SOURCE_DIR就会是子模块的源码目录,而不是最外层的目录,构建的目录PROJECT_BINARY_DIR会编程build/<源码相对路径>

project初始化:LANGUAGES 字段

目前支持的语言包括:C/CXX/ASM/Fortran/CUDA/OBJC/OBJCXX/ISPC 如果不指定LANGUAGES,默认为C/CXX

# 第一种
project(hellocmake LANGUAGES CXX)
# 第二种
project(hellocmake LANGUAGES C CXX)
# 第三种
project(hellocmake LANGUAGES NONE)
enable_language(CXX)
project初始化:VERSION字段
# project(hellocmake VERSION x.y.z)
project(hellocmake VERSION 0.2.3)
message("PROJECT_NAME: ${PROJECT_NAME}")
message("PROJECT_VERSION: ${PROJECT_VERSION}")
message("PROJECT_VERSION_MAJOR: ${PROJECT_VERSION_MAJOR}")
message("PROJECT_VERSION_MINOR: ${PROJECT_VERSION_MINOR}")
message("PROJECT_VERSION_PATCH: ${PROJECT_VERSION_PATCH}")message("hellocmake_VERSION: ${hellocmake_VERSION}")
message("hellocmake_VERSION: ${${PROJECT_NAME}_VERSION}")
  • PROJECT_VERSION_MAJOR:获取版本号x(主版本号)
  • PROJECT_VERSION_MINOR:获取版本号y(次版本号)
  • PROJECT_VERSION_PATCH:获取版本号z(补丁版本号)
project 内的其他字段
  • DESCRIPTION 项目描述
  • HOMEPAGE_URL 项目主页

设置C++标准

CMAKE_CXX_STANDARD

set(CMAKE_CXX_STANDARD 17) # 如果需要C++23 就把17修改为23
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)project(hellocmake LANGUAGES CXX)

CMAKE_CXX_STANDARD_REQUIRED:表示是否一定要支持你指定的标准,如果设置为OFF你的编译器不支持17则会默认使用14或者更低的方式编译,否则会报错,更安全

CMAKE_CXX_EXTENSIONS:也是BOOL类型,默认为ON,设置为ON的时候表示启用gcc的一些扩展功能;否则则关闭gcc的扩展功能,只使用标准的c++。如果你要兼容其他编译器(比如msvc)一般都是设置为OFF,防止不小心使用了gcc才有的特性

此外,最好是在设置project指令之前设置这些变量,这样可以在project中对编译器进行检测是否支持C++17的特性

常见误区
  • 请勿直接修改CMAKE_CXX_FLAGS 来添加-std=c++17,而是使用封装好的CMAKE_CXX_STANDARD

这会导致非gcc用户无法使用,且如果用户设置了CMAKE_CXX_STANDARD会跟该参数冲突。

链接库文件

add_library(mylib STATIC mylib.cpp)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)
  • STATIC:静态库
  • SHARED:动态库
  • OBJECT:对象库(不会生成.a文件,只会由CMake记住了生成哪些对象文件)只是为了组织代码结构

如果add_library没有参数会根据BUILD_SHARED_LIBS这个变量来决定是动态库还是静态库,如果设置为ON则是动态库,设置为OFF则是静态库,如果未指定BUILD_SHARED_LIBS,则默认为静态库

如果你发现一个项目中add_library都是无参的,则你可以使用cmake -B build -DBUILD_SHARED_LIBS:BOOL=ON来让他全部生成动态库

常见坑点:

动态库无法链接静态库,下面的可能会报一个cannot rellocate…的错误

add_library(otherlib STATIC otherlib.cpp)
add_library(mylib SHARED mylib.cpp)
target_link_libraries(mylib PUBLIC otherlib)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)

解决办法:把静态库编译成对象库或者让静态库编译时也生成位置无关的代码PIC,这样才能装在动态库中

# 方式一:会导致不需要PIC的库也变成PIC库了
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_library(otherlib STATIC otherlib.cpp)
add_library(mylib SHARED mylib.cpp)
target_link_libraries(mylib PUBLIC otherlib)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)
# 方式二:只针对otherlib来设置
add_library(otherlib STATIC otherlib.cpp)
set_property(TARGET otherlib PROPERTY CMAKE_POSITION_INDEPENDENT_CODE ON)
add_library(mylib SHARED mylib.cpp)
target_link_libraries(mylib PUBLIC otherlib)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)

在链接库的时候,假如你一定要使用动态链接库,你可以使用类似下面的代码(Windows对动态链接库不是很友好)

#ifdef _MSC_VER
__declspec(dllexport)
#endif
void say_hello()
{std::cout << "Hello, World!" << std::endl;
}
#ifdef _MSC_VER
__declspec(dllimport)
#endif
void say_hello();

CMAKE中对象的属性

add_executable(main main.cpp)
# 设置C++标准
set_property(TARGET main PROPERTY CMAKE_CXX_STANDARD 17)
# 如果编译器不支持对应的c++标准则报错
set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED ON)
# 在windows中运行时不启动控制台窗口
set_property(TARGET main PROPERTY WIN32_EXECUTABLE ON)
# 告诉编译器不要自动剔除没有引用符号的链接库
set_property(TARGET main PROPERTY LINK_WHAT_YOU_USE ON)
# 设置动态链接库的输出路径
set_property(TARGET main PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
# 设置静态链接库的输出路径
set_property(TARGET main PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
# 设置可执行文件的输出路径
set_property(TARGET main PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
set_target_properties(main PROPERTIES CMAKE_CXX_STANDARD 17CXX_STANDARD_REQUIRED ONCXX_STANDARD_REQUIRED ONLINK_WHAT_YOU_USE ONLIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libRUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin
)

另一种方式是通过全局变量,让之后创建的所有对象都享有相同的属性

set(CMAKE_CXX_STANDARD 17)
set(CXX_STANDARD_REQUIRED ON)
set(CXX_STANDARD_REQUIRED ON)
set(LINK_WHAT_YOU_USE ON)
set(LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
add_executable(main main.cpp)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/output/debug)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/output/debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/output/debug)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/output/release)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/output/release)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/output/release)

链接第三方库

# 方式一:对windows不友好
add_executable(main main.cpp)
target_link_libraries(main PUBLIC tbb)
# 方式二:因为路径的原因无法跨平台
add_executable(main main.cpp)
target_link_libraries(main PUBLIC /path/tbb.lib)
# 方式三:find_package,这会到环境变量中找到对应的包,有些冷门的库需要自己写find
add_executable(main main.cpp)
find_package(TBB REQUIRED)
target_link_libraries(main PUBLIC TBB::tbb)
# 方式四:自己查询对应位置的lib,最好保证库在自己的位置
file(GLOB LIB_LODEGEN ${PROJECT_SOURCE_DIR}/third_party/loadgen/lib/*.lib)
link_directories(${PROJECT_SOURCE_DIR}/third_party/loadgen/lib)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC ${LIB_LODEGEN})

如果使用位置不在环境变量中,如何使用find_package查询对应的包呢?

# 方式一
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} C:/Qt/5.15.2/msvc2019_64/lib/cmake)
# 方式二
set(Qt5_DIR C:/Qt/5.15.2/msvc2019_64/lib/cmake)
# 方式三 可以在编译的时候指定Qt5_DIR

第三方库后面追加REQUIRED会在找不到的时候会报错,如果不加的话就是会将TBB_FOUND变量设置为FALSE可以自己去判断

# 方式一
find_package(TBB)
if (TBB_FOUND)......
endif()
# 方式二
find_package(TBB)
if (TARGET TBB::tbb)......
else()
endif()

输出和变量

message("Hello CMake")                 # 调试信息
message(STATUS "Hello CMake")          # 状态信息 打印的东西带--
message(WARNING "Hello CMake")         # 黄色的警告信息
message(AUTHOR_WARNING "Hello CMake")  # 作者看到的警告信息, 可以编译的时候使用-Wno-dev关闭该警告
message(FATAL_ERROR "Hello CMake")     # 错误信息,并停止之后的指令
message(SEND_ERROR "Hello CMake")      # 错误信息,不停止之后的指令
set(myvar "Hello CMake")
message("myvar: ${myvar}")             # 打印变量

注意:如果要打印东西或者设置变量的时候,最好将变量添加""否则可能会被认为是参数

变量和缓存

如果重复执行cmake -B build会怎么样?

第二次执行会少很多输出,因为cmake会缓存相关的结果(自己去看对应的输出)

这样会造成一些因缓存造成的问题,这种可以使用删除build文件夹来让cmake重新检测,但是这样编译的中间结果全部需要重新编译,我们只需要重新检测CMakeCache.txt文件即可重新整理环境的缓存,如果因为build的中间文件错误,还是需要删除build文件夹来重新生成。

# 设置自己的缓存变量
set(myvar "hello" CACHE STRING "this is the docstring")
message("myvar: ${myvar}")
# 这种会强制更新缓存
set(myvar "hello" CACHE STRING "this is the docstring" FORCE)
message("myvar: ${myvar}")

使用上面的代码,我们可以在CMakeCache.txt看到我们自己的变量

缓存变量类型

  • STRING:字符串
  • FILEPATH:文件路径
  • PATH:目录路径
  • BOOL:布尔值

针对bool类型,cmake变量有一个简写的写法

option(WITH_TEST "set with test" ON)
# 上面的就等价
set(WITH_TEST ON CACHE BOOL "set with test")

如果配置完成,需要使用下面的命令来修改或者是删除缓存来修改,或者不使用option,改为set并加FORCE强制更新

cmake -B build -DWITH_TEST:BOOL=OFF

跨平台和编译器

int main()
{
#ifdef MY_MACRO...
#else...
#endif
}
add_executable(main main.cpp)
target_compile_definitions(main PUBLIC MY_MACRO=233) # 相当于在代码中定义宏MY_MACRO=233

判断操作系统

# 方式一
if (CMAKE_SYSTEM_NAME MATCHES "Windows")target_compile_definitions(main PUBLIC MY_NAME="Windows")
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")target_compile_definitions(main PUBLIC MY_NAME="Linux")
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")target_compile_definitions(main PUBLIC MY_NAME="Darwin")
endif()
# 方式二
if (WIN32)target_compile_definitions(main PUBLIC MY_NAME="Windows")
elseif (UNIX AND NOT APPLE)target_compile_definitions(main PUBLIC MY_NAME="Linux")
elseif (APPLE)target_compile_definitions(main PUBLIC MY_NAME="Darwin")
endif() 
# 方式三 使用生成器表达式
target_compile_definitions(main PUBLIC $<$<PLATFORM_ID:WINDOWS>:MY_NAME="Windows">$<$<PLATFORM_ID:Linux>:MY_NAME="Linux">$<$<PLATFORM_ID:Darwin,FreeBSD>:MY_NAME="Darwin">
)

判断编译器

# 方式一
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")target_compile_definitions(main PUBLIC MY_NAME="gcc")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "NVIDIA")target_compile_definitions(main PUBLIC MY_NAME="nvcc")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")target_compile_definitions(main PUBLIC MY_NAME="clang")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")target_compile_definitions(main PUBLIC MY_NAME="msvc")
endif()
# 方式二 使用生成器表达式
target_compile_definitions(main PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>:MY_NAME="Open-Source">$<$<CXX_COMPILER_ID:MSVC,NVIDIA>:MY_NAME="Commercial">
)
target_compile_definitions(main PUBLIC $<$AND:$<CXX_COMPILER_ID:GNU,Clang>, $<PLATFORM_ID:Linux>>:MY_NAME="Open-Source">
)
# 方式三
if (MSVC)target_compile_definitions(main PUBLIC MY_NAME="MSVC")
elseif (CMAKE_COMPILER_IS_GNUCC)target_compile_definitions(main PUBLIC MY_NAME="GCC")
else()target_compile_definitions(main PUBLIC MY_NAME="Other")
endif() 

分支与判断

BOOL类型的值

if 中的变量的特点:可以不需要加${},会自动尝试作为变量名来求值

CMake是区分大小写的哦(针对变量),只有指令是不分大小写的

if (DEFINED xx) 判断某个变量是否被定义,但是如果设置为空,不代表变量未定义,不加DEFINED可以判断变量是否为空

ENV{xx}可以判断环境变量是否被定义

set(ENV{MYVAR} "aaa")
if (DEFINED ENV{MVVAR})
endif()

变量的作用域

父模块的变量会传递给子模块,但是子模块的变量,父模块式感知不到的,但是在设置变量的时候,在最后增加PARENT_SCORER之后,父模块就可以感知到了

  • include中的xxx.cmake没有独立的作用域

  • add_subdirectory的CMakeLists.txt有独立的作用域

  • macro没有独立的作用域

  • function有独立的作用域,PARENT_SCORER也可用于function的返回值

子模块如何向父模块传递变量

  • 使用缓存变量(不推荐,因为会对所有模块可见)
  • 设置环境变量$ENV{xx}
  • 读取缓存变量$CACHE{CMAKE_BUILD_TYPE}

其他

自己去发现吧,我这里先不写啦

一个CMakeList.txt模板

cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)project(hellocmake LANGUAGES CXX)if (PROJECT_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR)message(WARNING "this binary dir of cmake cannot be the same as source dir")
endif()if (NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE Release)
endif()if (WIN32)add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES)
endif()if (NOT MSVC)find_program(CCACHE_PROGRAM ccache)if (CCACHE_PROGRAM)message(STATUS "Found CCache: ${CCACHE_PROGRAM}")set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PROGRAM})endif()
endif()file(GLOB SOURCES src/*.cpp)if (WIN32)add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")add_executable(${PROJECT_NAME} WIN32 ${SOURCES})
else()add_executable(${PROJECT_NAME} ${SOURCES})
endif()

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

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

相关文章

JWT令牌、过滤器Filter、拦截器Interceptor

目录 JWT令牌 简介 JWT生成 解析JWT 登陆后下发令牌 过滤器(Filter) Filter快速入门 Filter拦截路径 过滤器链 登录校验Filter-流程 拦截器(Interceptor) Interceptor 快速入门 拦截路径 登录校验流程 JWT令牌 简介 全称:JSON Web Token(https://iwt.io/) …

Oracle复习部分记录

GuassDB,Oracle,Postgresql 适用的hint说明 一、在使用with as 短语时&#xff0c;使用materialize 会生产临时表&#xff0c;执行完成后&#xff0c;PGA会将其清除。 materialize 二、pq_distribute 表示在并行过程中&#xff0c;按照并行对标划分多少个分区&#xff0c;a分…

0118__C语言——float.h文件

C语言——float.h文件_c float.h-CSDN博客

React 中的事件处理

React 中是如何处理事件的&#xff0c;现在下面简单的一段代码&#xff1a; export default function App() {const AList lazy(()>import(./List.js))const r useRef(null) const [show, setShow] useState(false);return (<><button onFocus{()>{setShow…

【StructueEngineering】Wind Load Combination Patterns风荷载组合模式

文章目录 Combination PatternsBasic Rules of Combinations组合的基本规律Specific Combination Patterns1. First 8 Combinations (1 to 8)2. Middle 8 Combinations (9 to 16)3. Last 8 Combinations (17 to 24) Summary of CombinationsKey Variables and Parameters with …

Postgre 调优工具pgBadger部署

一&#xff0c;简介&#xff1a; pgBadger&#xff08;日志分析器&#xff09;类似于oracle的AWR报告&#xff08;基于1小时&#xff0c;一天&#xff0c;一周&#xff0c;一月的报告&#xff09;&#xff0c;以图形化的方式帮助DBA更方便的找到隐含问题。 pgbadger是为了提高…

轻松上手MYSQL:探索MySQL索引数据结构的奥秘-让数据库飞起来

​&#x1f308; 个人主页&#xff1a;danci_&#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》&#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索MYSQL索引数据结构之旅✨ &#x1f44b; 大家好&#xff01;文本学习研…

代理IP协议有何区别?深入了解 SOCKS5、HTTP 代理

在数字通信领域&#xff0c;数据安全和匿名性都是非常重要的指标。互联网的不断发展催生了几种协议&#xff0c;每种协议都有独特的优势和挑战。其中&#xff0c;SOCKS5 代理、HTTP代理最为广泛使用&#xff0c;下面给大家一起讨论&#xff0c;HTTP代理与 SOCKS5代理&#xff0…

【技术】JS 操作剪贴板

JS 操作剪贴板 1、原生 JS 操作剪贴板复制文本2、原生 JS 操作剪贴板读取图片实现异步上传navigator 对象监听粘贴事件 3、剪贴板插件 1、原生 JS 操作剪贴板复制文本 在博客类网站看到一段代码&#xff0c;想复制&#xff0c;如果代码量比较大&#xff0c;选中内容复制会比较…

基于python深度学习的CNN图像识别鲜花-含数据集+pyqt界面

代码下载&#xff1a; https://download.csdn.net/download/qq_34904125/89383615 本代码是基于python pytorch环境安装的。 下载本代码后&#xff0c;有个requirement.txt文本&#xff0c;里面介绍了如何安装环境&#xff0c;环境需要自行配置。 或可直接参考下面博文进行…

WPF 使用Image控件显示图片

Source属性 Source属性用来告诉Image组件要展示哪张图片资源的一个入口&#xff0c;通常是图片的路径。也许是本地路径&#xff0c;也许是网络路径。 本地图片路径加载方式 使用相对路径&#xff0c;相对于工程目录的路径&#xff0c;当设置Width属性时&#xff0c;图片会等…

Linux:基础IO(二.缓冲区、模拟一下缓冲区、详细讲解文件系统)

上次介绍了&#xff1a;Linux&#xff1a;基础IO&#xff08;一.C语言文件接口与系统调用、默认打开的文件流、详解文件描述符与dup2系统调用&#xff09; 文章目录 1.缓冲区1.1概念1.2作用与意义 2.语言级别的缓冲区2.1刷新策略2.2具体在哪里2.3支持格式化 3.自己来模拟一下缓…

FFMpeg解复用流程

文章目录 解复用流程图复用器与解复用器小结 解复用流程图 流程图&#xff0c;如上图所示。 复用器与解复用器 复用器&#xff0c;就是视频流&#xff0c;音频流&#xff0c;字幕流&#xff0c;其他成分&#xff0c;按照一定规则组合成视频文件&#xff0c;视频文件可以是mp4…

Linux各目录的作用

Linux各目录的作用 目录作用~登录用户对应的目录.当前工作目录$PATH环境变量/根目录/boot启动Linux使用的文件&#xff0c;例如Linux内核&#xff0c;包括连接文件和镜像文件&#xff0c;&#xff08;删了就启动不了了&#xff09;/bin(/usr/bin,/usr/local/bin)Binary&#x…

如何在vector中插入和删除元素?

在C的std::vector中插入和删除元素通常使用其成员函数来完成。以下是如何在std::vector中插入和删除元素的示例&#xff1a; 插入元素 在末尾插入元素&#xff1a;使用push_back函数。 cpp复制代码 #include <vector> int main() { std::vector<int> v; v.push_…

实现贪吃蛇小游戏【简单版】

1. 贪吃蛇游戏设计与分析 1.1 地图 我们最终的贪吃蛇大纲要是这个样子&#xff0c;那我们的地图如何布置呢&#xff1f; 这里不得不讲⼀下控制台窗口的⼀些知识&#xff0c;如果想在控制台的窗口中指定位置输出信息&#xff0c;我们得知道该位置的坐标&#xff0c;所以首先介…

CPN Tools学习——从平面网构建分层 PN

1.先创建平面petri网 创建如下petri网&#xff1a; CPN ide创建petri网真的舒服很多&#xff0c;但是教程又是CPN Tools的&#xff0c;我的想法是看两个版本能不能互通&#xff0c;在前者创建&#xff0c;在后者运行学习。 新增定义&#xff1a; colset E unit with e; 但…

nginx全解

一、Nginx配置文件 1.1 主配置文件 主配置文件位置&#xff1a;nginx.conf tip&#xff1a;安装方式不同&#xff0c;路径不同 #主配置文件格式 ​ main block&#xff1a;主配置段&#xff0c;即全局配置段&#xff0c;对http,mail都有效 ​ #配置Nginx服务器的事件模块相…

深度学习 --- stanford cs231学习笔记三(卷积神经网络CNN)

卷积神经网络CNN 1&#xff0c;有效的利用了图像的空间信息/局部感受野 全连接神经网络中的神经是由铺平后的所有像素计算决定。 由于计算时是把图像的所有像素拉成了一条线&#xff0c;因此在拉伸的同时也损失了图像像素之间固有的空间信息。 卷积层中的神经只由5x5x3(假设fil…