CMAKE使用记录

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 targetCONFIGURATIONS DebugRUNTIME DESTINATION Debug/bin)
install(TARGETS targetCONFIGURATIONS ReleaseRUNTIME DESTINATION Release/bin)

PERMISSIONS 权限:

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

举例:

INSTALL(TARGETS myrun mylib mystaticlibRUNTIME DESTINATION binLIBRARY DESTINATION libARCHIVE 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/myprojPATTERN "CVS" EXCLUDEPATTERN "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.rhkb.cn/news/150248.html

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

相关文章

华为云云耀云服务器L实例评测|Ubuntu云锁防火墙安装搭建使用

华为云云耀云服务器L实例评测&#xff5c;Ubuntu安装云锁防火墙对抗服务器入侵和网络攻击 1.前言概述 华为云耀云服务器L实例是新一代开箱即用、面向中小企业和开发者打造的全新轻量应用云服务器。多种产品规格&#xff0c;满足您对成本、性能及技术创新的诉求。云耀云服务器L…

DRM全解析 —— CRTC详解(1)

本文参考以下博文&#xff1a; Linux内核4.14版本——drm框架分析(4)——crtc分析 特此致谢&#xff01; 1. 简介 CRTC实际上可以拆分为CRTC。CRT的中文意思是阴极摄像管&#xff0c;就是当初老电视上普遍使用的显像管&#xff08;老电视之所以都很厚&#xff0c;就是因为它…

基于水循环优化的BP神经网络(分类应用) - 附代码

基于水循环优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于水循环优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.水循环优化BP神经网络3.1 BP神经网络参数设置3.2 水循环算法应用 4.测试结果&#x…

TomCat关键技术

一、Tomcat 是什么 Tomcat 是一个 HTTP 服务器。通过前面的学习,我们知道HTTP 协议就是 HTTP 客户端和 HTTP 服务器之间的交互数据的格式,同时也通过 ajax 和 Java Socket 分别构造了 HTTP 客户端。HTTP 服务器我们也同样可以通过 Java Socket 来实现. 而 Tomcat 就是基于 J…

烟花爆竹厂如何做到0风险0爆炸事故?AI+视频监控平台给出答案

由于烟花爆竹具有易燃易爆风险&#xff0c;稍有不慎就会发生严重事故&#xff0c;而烟花爆竹厂区作为大量烟花爆竹存放地点&#xff0c;厂区面积大、工作人员杂乱&#xff0c;甚至有很多厂区原料存放不当&#xff0c;给日常的安全管理带来极大的压力&#xff0c;利用信息化手段…

普通交换机可以改成POE供电吗?

PoE交换机是一种可以通过网线为远程设备提供网络供电的交换机。它是PoE供电系统中常见的供电设备。然而&#xff0c;假如一个交换机本身没有PoE功能&#xff0c;是否可以通过添加一个PoE供电模块来为接入点提供供电呢&#xff1f; 事实上是可行的&#xff0c;简单地说就是利用了…

【轻松玩转MacOS】基本操作篇

引言 本文是系列的开篇&#xff0c;我将为大家介绍MacOS的基本操作。对于初次接触MacOS的用户来说&#xff0c;掌握这些基本操作是必不可少的。无论是启动和关机&#xff0c;还是使用键盘和鼠标&#xff0c;或者是快捷键的使用&#xff0c;这些基本操作都是你开始使用MacOS的第…

Cocos Creator3.8 项目实战(七)Listview 控件的实现和使用

滚动列表在游戏中也很常见&#xff0c;比如排行榜 、充值记录等&#xff0c;在这些场景中&#xff0c;都有共同的特点&#xff0c; 那就是&#xff1a;数据量大 &#xff0c; 结构相同。 在cocoscreator 中&#xff0c;没有现成的 Listview 控件&#xff0c; 无奈之下&#xff…

NEFU数字图像处理(1)绪论

一、简介 1.1什么是数字图像 图像是三维场景在二维平面上的影像。根据其存储方式和表现形式&#xff0c;可以将图像分为模拟图像和数字图像两大类 图像处理方法&#xff1a;光学方法、电子学方法 模拟图像&#xff1a;连续的图像数字图像&#xff1a;通过对时间上和数值上连续…

【拿完年终奖后】想要转行网络安全,一定不要错过这个时间段。

网络安全&#xff0c;作为当下互联网行业中较为热门的岗位&#xff0c;薪资可观、人才需求量大&#xff0c;作为转行必考虑。 在这里奉劝所有零基础想转行&#xff08;入门&#xff09; 网络安全的朋友们 在转行之前&#xff0c;一定要对网络安全行业做一个大概了解&#xf…

Java卷上天,可以转行干什么?

小刚是某名企里的一位有5年经验的高级Java开发工程师&#xff0c;每天沉重的的工作让他疲惫不堪&#xff0c;让他萌生出想换工作的心理&#xff0c;但是转行其他工作他又不清楚该找什么样的工作 因为JAVA 这几年的更新实在是太太太……快了&#xff0c;JAVA 8 都还没用多久&am…

【算法|动态规划No.13】leetcode LCR 166. 珠宝的最高价值

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

计算机视觉——飞桨深度学习实战-起始篇

后面我会直接跳到实战项目&#xff0c;将计算机视觉的主要任务和目标都实现一遍&#xff0c;但是需要大家下去自己多理解和学习一下。例如&#xff0c;什么是深度学习&#xff0c;什么是计算机视觉&#xff0c;什么是自然语言处理&#xff0c;计算机视觉的主要任务有哪些&#…

121-宏免杀

CS生成宏&上线 生成宏 1.cs生成宏&#xff0c;如下图操作 2.点击复制宏代码&#xff0c;保存下来 cs上线 注&#xff1a;如下操作使用的是word&#xff0c;同样的操作也适用于Excel 1.新建一个word文档&#xff0c;使用word打开。点击文件—— 2.更多——选项—— 3.自定义…

(三)行为模式:8、状态模式(State Pattern)(C++示例)

目录 1、状态模式&#xff08;State Pattern&#xff09;含义 2、状态模式的UML图学习 3、状态模式的应用场景 4、状态模式的优缺点 &#xff08;1&#xff09;优点 &#xff08;2&#xff09;缺点 5、C实现状态模式的实例 1、状态模式&#xff08;State Pattern&#x…

大数据软件项目的验收流程

大数据软件项目的验收流程是确保项目交付符合预期需求和质量标准的关键步骤。以下是一般的大数据软件项目验收流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.项目验收计划制定&#xff1a; 在…

工业路由器项目应用(4g+5g两种工业路由器项目介绍)

引言&#xff1a; 随着工业智能化的不断发展&#xff0c;工业路由器在各个领域的应用越来越广泛。本文将介绍两个工业路由器项目的应用案例&#xff0c;一个是使用SR500 4g工业路由器&#xff0c;另一个是使用SR800 5g工业路由器。 详情&#xff1a;https://www.key-iot.com/i…

STM32+USB3300复位枚举异常的问题

关键字&#xff1a;STM32F4&#xff0c;STM32H7&#xff0c;USB3300&#xff0c;USBHS&#xff0c;Reset复位 F4和H7用的都是DWC2的USBIP&#xff0c;我的板子上3300单片机工作的很好&#xff0c;插入枚举一切正常&#xff0c;但是设备收到上位机的复位命令后&#xff0c;单片…

新手选MT4还是MT5,anzo capital昂首资本建议选择MT4,一个原因

在交易中就订单执行策略而言&#xff0c;MT4和MT5哪个更好&#xff0c;相信很多交易者和&#xff0c;anzo capital昂首资本一样很难做出判断。在MT5中&#xff0c;虽然开发人员对发送订单的流程进行了额外的复杂化&#xff0c;同时MT5在订单执行政策方面的优势在于其能够调整全…