cmake:在各级目录之间共享变量(cmake cache变量)
摘要:
本文记录一下 CMake 变量的定义、原理及其使用。CMake 变量包含 Normal Variables、Cache Variables。通过 set 指令可以设置两种不同的变量。也可以在 CMake 脚本中使用和设置环境变量。set(ENV{} …),本文重点讲述 CMake 脚本语言特有的两种变量。
正文:
1、两种变量的定义参考
Normal Variables
通过 set( … [PARENT_SCOPE])这个命令来设置的变量就是 Normal Variables。例如 set(MY_VAL “6”) ,此时 MY_VAL 变量的值就是 6。
Cache Variables
通过 set( … CACHE [FORCE])这个命令来设置的变量就是 Cache Variables。例如 set(MY_CACHE_VAL “666” CACHE STRING INTERNAL),此时 MY_CACHE_VAL 就是一个 CACHE 变量。
2、Cache Variables
相当于一个全局变量,我们在同一个 cmake 工程中都可以使用。Cache 变量有以下几点说明:
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/3rd_party CACHE INTERNAL "")
# SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/3rd_party)MESSAGE(STATUS "CMAKE_MODULE_PATH :${CMAKE_MODULE_PATH}")
Cache 变量 CMAKE_INSTALL_PREFIX 默认值是 /usr/local (可以在生成的 CMakeCache.txt 文件中查看),这时候如果我们 在某个 CMakeLists.txt 中,仍然使用 set(CMAKE_INSTALL_PREFIX “/usr”),那么此时我们 install 的时候,CMake 以后面的 /usr 作为 CMAKE_INSTALL_PREFIX 的值,这是因为 CMake 规定,有一个与 Cache 变量同名的 Normal 变量出现时,后面使用这个变量的值都是以 Normal 为准,如果没有同名的 Normal 变量,CMake 才会自动使用 Cache 变量。
所有的 Cache 变量都会出现在 CMakeCache.txt 文件中。这个文件是我们键入 cmake .命令后自动出现的文件。打开这个文件发现,CMake 本身会有一些默认的全局 Cache 变量。例如:CMAKE_INSTALL_PREFIX、CMAKE_BUILD_TYPE、CMAKE_CXX_FLAGSS 等等。可以自行查看。当然,我们自己定义的 Cache 变量也会出现在这个文件中。Cache 变量定义格式为 set( CACHE STRING INTERNAL)。这里的 STRING可以替换为 BOOL FILEPATH PATH ,但是要根据前面 value 类型来确定。参考。
修改 Cache 变量。可以通过 set( CACHE INSTERNAL FORCE),另一种方式是直接在终端中使用 cmake -D var=value …来设定默认存在的CMake Cache 变量。
下面通过一个例子来说明以上三点:
首先看一下目录树结构:
$ tree
├── CMakeLists.txt
└── src└── CMakeLists.txt
1 directory, 2 files
根目录 CMakeLists.txt 文件内容如下:
cmake_minimum_required(VERSION 3.10)
set(MY_GLOBAL_VAR "666" CACHE STRING INTERNAL )
message("第一次在父目录 CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
message("第一次在父目录 MY_GLOBAL_VAR=${MY_GLOBAL_VAR}")
add_subdirectory(src)
message("第二次在父目录 CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
message("第二次在父目录 MY_GLOBAL_VAR=${MY_GLOBAL_VAR}")
set(CMAKE_INSTALL_PREFIX "-->usr" )
message("第三次在父目录 CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
src/CMakeLists.txt 文件内容如下:cmake_minimum_required(VERSION 3.10)
message("子目录,CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
message("子目录,MY_GLOBAL_VAR=${MY_GLOBAL_VAR}")
set(CMAKE_INSTALL_PREFIX "/usr" CACHE STRING INTERNAL FORCE)
set(MY_GLOBAL_VAR "777" CACHE STRING INTERNAL FORCE )
运行结果:
$ cmake .
第一次在父目录 CMAKE_INSTALL_PREFIX=/usr/local
第一次在父目录 MY_GLOBAL_VAR=666
子目录,CMAKE_INSTALL_PREFIX=/usr/local
子目录,MY_GLOBAL_VAR=666
第二次在父目录 CMAKE_INSTALL_PREFIX=/usr
第二次在父目录 MY_GLOBAL_VAR=777
第三次在父目录 CMAKE_INSTALL_PREFIX=-->usr
程序说明:首先在根目录中打印一下当前的 Cache 变量 CMAKE_INSTALL_PREFIX 值,主要看看默认值是什么,然后在子目录 src/CMakeLists.txt 中再次打印和修改该 Cache 值,目的是熟悉修改全局 Cache 变量,当返回根目录 CMakeLists.txt 文件中再次执行第二次打印该 Cache 值时,主要看一看在子目录中修改后的效果。接着在根目录中设定一个 CMAKE_INSTALL_PREFIX 的 Normal 同名变量,此时第三次打印 CMAKE_INSTALL_PREFIX 的值,此时是为了证明,当有与 Cache 同名的 Normal 变量出现时,CMake 会优先使用 Normal 属性的值。通过设定 MY_GLOBAL_VAR 主要是为了说明可以自己设定全局 Cache 变量。最后的结果如上面显示,当我们再次执行 cmake . 的时候,程序结果如下:
$ cmake .
第一次在父目录 CMAKE_INSTALL_PREFIX=/usr
第一次在父目录 MY_GLOBAL_VAR=777
子目录,CMAKE_INSTALL_PREFIX=/usr
子目录,MY_GLOBAL_VAR=777
第二次在父目录 CMAKE_INSTALL_PREFIX=/usr
第二次在父目录 MY_GLOBAL_VAR=777
第三次在父目录 CMAKE_INSTALL_PREFIX=-->usr
可以发现第一次在父目录打印 CMAKE_INSTALL_PREFIX 和 MY_GOLBAL_VAR 时,他们的结果是上次cmake .后生成的值,存储在 CMakeCache.txt 中,自己可以找到,解决方案就是可以把 CMakeCache.txt 文件删除,然后在 cmake .我们以后在实际使用时要注意这个坑。对于修改 Cache 变量的另一种方式就是cmake -D CMAKE_INSTALL_PREFIX=/usr。可以自己验证。这里说一个重要的点,就是在终端中输入的 cmake -D var=value . 如果 CMake 中默认有这个 var Cache 变量,那么此时就是赋值,没有的话,CMake 就会默认创建了一个全局 Cache 变量然后赋值。(tips: $CACHE{VAR}表示获取 CACHE 缓存变量的值)。例子如下:(目录结构同上)
根目录 CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
set(MY_GLOBAL_VAR "666")
message("第一次在父目录 MY_GLOBAL_VAR=$CACHE{MY_GLOBAL_VAR}")
add_subdirectory(src)
message("第二次在父目录局部 MY_GLOBAL_VAR=${MY_GLOBAL_VAR}")
message("第二次在父目录全局 MY_GLOBAL_VAR=$CACHE{MY_GLOBAL_VAR}")
src/CMakeLists.txt :cmake_minimum_required(VERSION 3.10)
message("子目录,MY_GLOBAL_VAR=${MY_GLOBAL_VAR}")
set(MY_GLOBAL_VAR "777" CACHE STRING INTERNAL FORCE )
运行结果:
第一次在父目录 MY_GLOBAL_VAR=8
子目录,MY_GLOBAL_VAR=666
第二次在父目录局部 MY_GLOBAL_VAR=666
第二次在父目录全局 MY_GLOBAL_VAR=777
有了上面的基础,相信这个例子很快能看明白。
3、两种变量的作用域原理及使用
1、Normal Variables
作用域属于整个 CMakeLists.txt 文件,当该文件包含了 add_subdirectory()、include()、macro()、function()语句时,会出现两种不同的效果。
(1)、包含 add_subdirectory()、function()。(本质是值拷贝)
假设,我们在工程根目录 CMakeLists.txt 文件中使用 add_subdirectory(src) 包含另一个 src 目录,在 src 目录中有另一个 CMakeLists.txt 文件。在终端运行的目录结构如下:
$ tree
├── CMakeLists.txt
└── xxx└── CMakeLists.txt
1 directory, 2 files
以根目录 CMake 文件为父目录,src 目录为子目录,此时子目录 CMake 文件会拷贝一份父目录文件的 Normal 变量。需要说明的是,我们在子目录中如果想要修改父目录 CMake 文件包含的 Normal 变量。必须通过 set(… PARENT_SCOPE) 的方式。下面通过例子来说明。
在父/根目录的 CMakeLists.txt 文件内容如下:
cmake_minimum_required(VERSION 3.10)
message("父目录 CMakeLists.txt 文件")
set(MY_VAL "6")message("第一次在父目录 MY_VAL=${MY_VAL}")
add_subdirectory(src)
message("第二次在父目录,MY_VAL=${MY_VAL}")
在子目录 src/CMakeLists.txt 文件内容如下:cmake_minimum_required(VERSION 3.10)
message("进入子目录 src/CMakeLists.txt 文件")
message("在子目录,MY_VAL=${MY_VAL}")
message("退出子目录")
运行结果:
$ cmake .
```cpp
父目录 CMakeLists.txt 文件
第一次在父目录 MY_VAL=6
进入子目录 src/CMakeLists.txt 文件
在子目录,MY_VAL=6
退出子目录
第二次在父目录,MY_VAL=6
从结果可以看出,在子目录 CMake 文件中可以直接使用父目录定义的 MY_VAL 变量的值 6。当在子目录 CMake 文件中修改 MY_VAL 变量值,看看在父目录中 MY_VAL 的值如何变化。下面仅仅在子目录 CMake 文件中加入一行代码 set(MY_VAL “7”),最后的子目录 CMake 文件代码如下:
cmake_minimum_required(VERSION 3.10)
message("进入子目录 src/CMakeLists.txt 文件")
set(MY_VAL "7") # 刚刚加入的message("在子目录,MY_VAL=${MY_VAL}")
message("退出子目录")
运行结果:
$ cmake .```cpp
父目录 CMakeLists.txt 文件
第一次在父目录 MY_VAL=6
进入子目录 src/CMakeLists.txt 文件
在子目录,MY_VAL=7
退出子目录
第二次在父目录,MY_VAL=6
我们发现在 src/CMakeLists.txt 中打印的 MY_VAL 的值是 7,然后退出子目录回到根目录后,打印 MY_VAL 的值仍然是 6。**说明了:子目录的 CMakeLists.txt 文件仅仅是拷贝了一份父目录的 Normal 变量,即使在子目录 CMake 文件中修改了 MY_VAL 变量,那也只是子目录自己的变量,不是父目录的变量。**因为 Normal 变量的作用域就是以 CMakeLists.txt 文件为基本单元。那么我们如何在子目录 CMake 文件中修改父目录 CMake 文件的 Normal 变量呢? 我们需要在子目录 CMakeLists.txt 文件中设置 MY_VAL 时,加上 PARENT_SCOPE 属性。即用如下代码: set(MY_VAL “7” PARENT_SCOPE),子目录 CMakeLists.txt 文件如下:
cmake_minimum_required(VERSION 3.10)
message("进入子目录 src/CMakeLists.txt 文件")
set(MY_VAL "7" PARENT_SCOPE) # 修改处message("在子目录,MY_VAL=${MY_VAL}")
message("退出子目录")
运行结果:
$ cmake .
父目录 CMakeLists.txt 文件
第一次在父目录 MY_VAL=6
进入子目录 src/CMakeLists.txt 文件
在子目录,MY_VAL=6
退出子目录
第二次在父目录,MY_VAL=7
可以看出在第二次回到父目录时,MY_VAL 的值已经变成了 7。同理,对于 function() 最开始的结论也适用。代码如下:
c
make_minimum_required(VERSION 3.10)
message("父目录 CMakeLists.txt 文件")
set(MY_VAL "6")message("第一次在父目录 MY_VAL=${MY_VAL}")
函数定义
function(xyz test_VAL) # 函数定义处!set(MY_VAL "888" PARENT_SCOPE)message("functions is MY_VAL=${MY_VAL}")
endfunction(xyz)xyz(${MY_VAL}) # 调用函数
message("第二次在父目录,MY_VAL=${MY_VAL}")
运行结果:
父目录 CMakeLists.txt 文件
第一次在父目录 MY_VAL=6
functions is MY_VAL=6
第二次在父目录,MY_VAL=8
可以看出在该函数中使用 MY_VAL 这个变量值,其实就是一份父目录变量的值拷贝,此时打印值为 6。在 函数中修改值,那么也是用 set(${MY_VAL} 8 PARENT_SCOPE)。此时,退出函数第二次打印变量值时。该值就是在函数中修改好的值 8。 本质讲,对于 function() 而言,刚刚说到的父目录其实不是严格正确的。因为函数定义可以是在其他 .cmake 模块文件中定义的。也可以在其他 CMakeLists.txt 文件中调用,因此准确的说,这里的父目录应该改为『调用函数的地方所属的 CMakeLists.txt 』,我们做的这个实验是在根目录 CMakeLists.txt 文件中定义了函数,又在本文件中使用了。因此之前的说法理解其意思即可。对于 add_subdirectory() 而言,其实也是说调用的地方。下面的 include()、macro() 例子会涉及到,将 function() 放在一个外部的 .cmake 文件中。那里也会说明 function() 与 macro() 的不同。
(2)、包含 include()、macro() (本质有点类似 c 中的 #include 预处理含义)
现在在上面的根目录中加入了一个 cmake_modules 目录。目录中有一个 Findtest.cmake 文件。新的目录结构如下:
$ tree
├── CMakeLists.txt
├── cmake_modules
│ └── Findtest.cmake
└── src└── CMakeLists.txt
2 directories, 3 files
在根目录中的 CMakeLists.txt 文件包含的代码如下:
cmake_minimum_required(VERSION 3.10)
message("父目录 CMakeLists.txt 文件")
set(MY_VAL "6")
message("第一次在父目录 MY_VAL=${MY_VAL}")
使用 include() 文件的宏
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
include(Findtest) # 从 CMAKE_MODULE_PATH 包含的路径中搜索 Findtest.cmake 文件
#test(${MY_VAL}) # 调用宏
#xyz(${MY_VAL}) # 调用函数#find_package(test REQUIRED) # 从 CMAKE_MODULE_PATH 包含的路径中搜索 Findtest.cmake 文件 与 include () 两者的效果是一样的!message("第二次在父目录,MY_VAL=${MY_VAL}")message("include test=${test_VAL}")
#message("macro_val=${macro_val}")
cmake_modules/Findtest.cmake 文件内容如下:
该文件定义了一个函数以及一个宏
message("进入 Findtest.cmake 文件")set(test_VAL "222") # 验证根目录 CMake 文件能够访问这个变量
set(MY_VAL "000") # 测试 include() 效果
宏定义
macro(test MY_VA) # 定义一个宏!set(macro_val "1") # 宏内部定义变量message("macro is MY_VAL=${MY_VA}")set(MY_VAL "999") # 直接修改的就是调用该宏所处的文件中的 Normal 变量
endmacro(test)
函数定义
function(xyz test_VAL)set(MY_VAL "888" PARENT_SCOPE) # 修改 调用者的 变量message("function is MY_VAL=${MY_VAL}")
endfunction(xyz)
运行结果:
$ cmake .
父目录 CMakeLists.txt 文件
第一次在父目录 MY_VAL=6
进入 Findtest.cmake 文件
第二次在父目录,MY_VAL=000
include test=222
从结果可以看出,include() 内部是可以修改调用者 MY_VAL 变量。include() 包含的文件内定义的变量 test_VAL,也可以在调用 include() 的 CMakeLists.txt 文件中直接访问,同样的对于 macro() 也适用,在根目录 CMake 文件中调用宏,即取消 test(MYVAL)以及message("macroval={MY_VAL}) 以及 message("macro_val=MYVAL)以及message("macroval={macro_val}") 部分的注释,此时最后输出结果 :
$ cmake .
父目录 CMakeLists.txt 文件
第一次在父目录 MY_VAL=6
进入 Findtest.cmake 文件
macro is MY_VAL=000
第二次在父目录,MY_VAL=999
include test=222
macro_val=1
可以看出,这次输出的结果在第二次进入父目录后,MY_VAL 变量的值就是 999 了。注意到在根目录中 CMakeLists.txt 中 注释语句中有一个 find_package() ,这个和 include() 其实都是一样的结果。
总结:
结合 include() 、macro() 最后结果,能够得出一个结论:通过 include() 和 macro() 相当于把这两部分包含的代码直接加入根目录 CMakeLists.txt 文件中去执行,相当于他们是一个整体。因此变量直接都是互通的。这就有点像 C/C++ 中的 #include 包含头文件的预处理过程了。这一点其实与刚开始讲的 function() 、add_subdirectory() 完全不同,在函数以及 add_subdirectory() 中,他们本身就是一个不同的作用域范围,仅仅通过拷贝调用者的 Normal 值(仅仅在调用 add_subdirectory() / function() 之前的 Normal 变量),如果要修改调用者包含的 Normal 变量,那么只能通过 set(MY_VAL “某个值” PARENT_SCOPE)注明我们修改的是调用者 Normal 值。虽然在 C/C++ 中,可以通过指针的方式,通过函数可以修改外部变量值,但是在 CMake 脚本语言中 function() 虽然能够传入形式参数,但是者本质上就是 C/C++ 中的值拷贝。而不是引用。上面所说的 Normal 变量其实就是一个局部变量。
参考:
1、https://stackoverflow.com/questions/31037882/whats-the-cmake-syntax-to-set-and-use-variables/31044116#31044116
2、https://stackoverflow.com/questions/3249459/for-the-cmake-include-command-what-is-the-difference-between-a-file-and-a-mod
3、https://cmake.org/cmake/help/v3.11/command/set.html#set
4、https://blog.csdn.net/weixin_39732534/article/details/110658282
5、https://guoqiang.blog.csdn.net/article/details/122214424
相关文章:

antd+dva笔记
参考 React中函数式声明组件Dva Ant Design 前后端分离之 React 应用实践ReactDvaJS 之 hook 路由权限控制dva 知识地图react-router Guides and API docs (v2, v3)react-sage redux-saga 是一个用于管理 Redux 应用异步操作,可以用来代替 redux-thunk 中间件。《Redux-saga 中…

求两个矩形重叠部分的面积
#include<stdio.h> #include<math.h>#define areaFile "area.txt" #define perportionFile "perportion.txt"#define min(a,b) ( ((a)>(b)) ? (b):(a) ) #define max(a,b) ( ((a)>(b)) ? (a):(b) )typedef struct xy { int x; int y; …

session,cookie,sessionStorage,localStorage的区别及应用场景
浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互。 一、cookie和session cookie和session都是用来跟踪浏览器用户身份的会话方式。 区别: 1、保持状态:cookie保存在浏览器端&#x…

鱼眼镜头及其标定
1. 鱼眼镜头特性与镜头分类 普通镜头和针孔相机在数学模型上可以等价对待,都是射影变换(Perspective transform); 鱼眼镜头受到水下斯涅耳窗口现象的启发,采用不同的投影方式,来得到极大的视场角ÿ…

django -- url 的 name 属性
在html的form中使用给url定义的name值,可以在修改url时不用在修改form的src。 urls.py from django.conf.urls import url from mytest import viewsurlpatterns [# url(r^admin/, admin.site.urls),url(r^index/, views.index, namemysite), views.Index.as_view(…

两个矩形重叠部分面积
#include<stdio.h> #include<math.h> #define min(a,b) ( ((a)>(b)) ? (b):(a) ) #define max(a,b) ( ((a)>(b)) ? (a):(b) )typedef struct xy { int x; int y; }xy;void main() {xy a[4];int s,chang,kuang;while (true){printf("Please input 4 x,…

前百度面试官整理的——Java后端面试题(一)
2019独角兽企业重金招聘Python工程师标准>>> List 和 Set 的区别 List , Set 都是继承自 Collection 接口 List 特点:元素有放入顺序,元素可重复 , Set 特点:元素无放入顺序,元素不可重复,重复元…

vibe前景提取算法示例代码
//ViBe.h#pragma once #include <iostream> #include "opencv2/opencv.hpp"using namespace cv; using namespace std;#define NUM_SAMPLES 20 //每个像素点的样本个数 #define MIN_MATCHES 2 //#min指数 #define RADIUS 20 //Sqthere半径 #define SUBSAMPL…

Linux系统程序运行时加载动态库路径顺序
程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 链接时路径(Link-time path)和运行时路径(Run-time path)不是一回…

浮动元素会引起的问题和你的解决办法
问题: (1)父元素的高度无法被撑开,影响与父元素同级的元素(2)与浮动元素同级的非浮动元素会跟随其后(3)若非第一个元素浮动,则该元素之前的元素也需要浮动,否…

Visual Paradigm 教程[UML]:如何使用刻板印象和标记值?(下)
下载Visual Paradigm最新试用版 已加入在线订购,现在抢购立享特别优惠>> 将构造型应用于模型元素 接下来,我们将构造型应用于模型元素。右键单击Customer,然后从弹出菜单中选择Stereotypes> External User。 从图形上看…

基于opencv的简单视频处理类示例
#include "opencv2/opencv.hpp" using namespace std; using namespace cv; class VideoProcessor { private: VideoCapture caputure; //图像处理函数指针 void (*process)(Mat &,Mat &); bool callIt; string WindowNameInput; string WindowNa…

flex数据绑定
2019独角兽企业重金招聘Python工程师标准>>> 1 、方法绑定 [Bindable(event"myFlagChanged")] private function isEnabled():String { if (myFlag)return true; else return ‘false; } <mx:TextArea id"myTA" text"{isEnabled()}&…

【error】error: field * has incomplete type
在编译程序是出现了如题错误, 类或结构体有前向声明的用法,编译到这里时还没有发现定义,不知道该类或者结构的内部成员,没有办法具体的构造一个对象,所以会报错。 两种解决方法: 方法一:将类成员…

Web前端学习笔记:Vue生命周期理解
一、感谢原创博主 示例代码出处vue2.0 探索之路——生命周期和钩子函数的一些理解 官方文档 二、生命周期简单描述 总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。 创建前/后 在beforeCreated阶段,vue实例的挂载元素…

获取结构体中变量的偏移量
C/C获取结构体中变量的偏移量 1.某些特殊需求下,我们需要知道某个变量在其结构体中的偏移位置。 通常的做法就是定义一个宏变量,如下: #define OFFSET(structure, member) ((int64_t)&((structure*)0)->member) // 64位系统 #defin…

VS2010 CUDA 5.5 VA_X Win7 64位配置
一.安装CUDA5.5以及配置VS助手 1、安装之前必须确认自己电脑的GPU支持CUDA。在设备管理器中找到显示适配器(Display adapters),找到自己电脑的显卡型号,如果包含在http://www.nvidia.com/object/cuda_gpus.html的列表中,说明支持…

SmartRoute之大规模消息转发集群实现
为什么80%的码农都做不了架构师?>>> 消息转发的应用场景在现实中的应用非常普遍,我们常用的IM工具也是其中之一;现有很多云平台也提供了这种基础服务,可以让APP更容易集成相关功能而不必投入相应的开发成本。对于实现…

unity项目警告之 LF CRLF问题
unity中创建的脚本,以LF结尾。 Visual studio中创建的脚本,以 CRLF结尾。 当我们创建一个unity脚本后,再用VS打开编辑保存后,这个文件既有LF结尾符,也有CRLF结尾符。 解决办法:更改unity的代码生成模板&…

Eigen向量化内存对齐/Eigen的SSE兼容,内存分配/EIGEN_MAKE_ALIGNED_OPERATOR_NEW
1.总结 对于基本数据类型和自定义类型,我们需要用预编译指令来保证栈内存的对齐,用重写operator new的方式保证堆内存对齐。对于嵌套的自定义类型,申请栈内存时会自动保证其内部数据类型的对齐,而申请堆内存时仍然需要重写operat…

c/c++文件遍历
//CBrowseDir.h#pragma once#include <stdlib.h> #include <direct.h> #include <string.h> #include <io.h> #include <stdio.h> #include <iostream> using namespace std; class CBrowseDir { protected: //存放初始目录的绝对…

优化应用启动时的体验
2019独角兽企业重金招聘Python工程师标准>>> 对于应用的启动时间,只能是尽量的避免一些耗时的、非必要性的操作在主线程中,这样相对减少一部分启动的耗时,同时在等待第一帧显示的时间里,可以加入一些配置用来增加用户体…

系列四、SpringMVC响应数据和结果视图
2019独角兽企业重金招聘Python工程师标准>>> 项目结构如下 一、返回值分类 一 返回字符串 Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址,根据字符串最后跳转到对应jsp页面 第一步、导入依赖坐标文件、配置…

numpy数组切片:一维/二维/数组
文章目录numpy数组切片操作一维数组(冒号:)1、一个参数:a[i]2、两个参数:ba[i:j]3、三个参数:格式b a[i:j:s]4、例子二维数组(逗号,)取元素 X[n0,n1]切片 X[s0:e0,s1:e1…

行列式求值、矩阵求逆
#include <iostream> #include <string> #include <assert.h> #include <malloc.h> #include <iostream> #include <stdlib.h> #include <memory.h> #include <time.h>using namespace std;//动态分配大小位size的一维数组 te…

IP 地址子网划分
1.你所选择的子网掩码将会产生多少个子网2的x次方-2(x代表网络位借用主机的位数,即2进制为1的部分,现在的网络中,已经不需要-2,已经可以全部使用,不过需要加上相应的配置命令,例如CISCO路由器需要加上ip su…

git rebase 和 git merger
& git merge 在上图中,每一个绿框均代表一个commit。除了c1,每一个commit都有一条有向边指向它在当前branch当中的上一个commit。 图中的项目,在c2之后就开了另外一个branch,名为experiment。在此之后,master下的修…

matplotlib绘制三维轨迹图
1. 绘制基本三维曲线 # import necessary module from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt import numpy as np# load data from file # you can replace this using with open data1 np.loadtxt("./pos.txt") # print (data1) n…

求一个矩阵的最大子矩阵
#include <iostream> #include <string> #include <assert.h> #include <malloc.h> #include <iostream> #include <stdlib.h> #include <memory.h> #include <time.h> #include <limits.h>using namespace std;//动态分…

tcpdump抓包文件提取http附加资源
2019独角兽企业重金招聘Python工程师标准>>> 前面几篇文章铺垫了一大批的协议讲解,主要是为了提取pcap文件中http协议附加的资源。 1、解析pcap文件,分为文件格式头,后面就是数据包头和包数据了 2、分析每个包数据,数据…