cmake基础(3)——安装
一、简介
install命令用于指定安装时的规则,由于安装命令比较复杂,这里做一部分内容的介绍,后续用到再继续完善。
1.命令简介
本文档基于3.20,目前有6种安装方式。
install(TARGETS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])
首先是通用参数:
1.1 DESTINATION
指定安装的目标目录。参数后接路径,可以是相对路径也可以是绝对路径。
相对路径则是相对于CMAKE_INSTALL_PREFIX变量值。也可以在安装时通过DESTDIR修改。
make DESTDIR=/package/stage install
实际上,上述方式是在UNIX系统下,而更加常用的是使用--prefix选项
cmake --install binPath --prefix="destPath"
1.2 PERMISSIONS
指定被安装文件的权限。包括OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, WORLD_READ, WORLD_WRITE, WORLD_EXECUTE, SETUID, 和 SETGID。对于平台中不支持的权限则忽略。
1.3 CONFIGURATIONS
指定一个构建配置的列表(Debug,Release等),作用于之后的内容,不对之前的内容不生效。
对于这个参数,必须要提到的是,cmake的安装动作(配置)是由外部控制的:
cmake --install srcPath --config Debug|Release...
通过上述命令中的--config参数,来控制执行安装Debug内容还是Release内容。
而对于当前配置CONFIGURATIONS则是表示其后内容隶属的动作(在Debug,Release还是其他动作时执行)。比如下面的例子:
install(TARGETS ${PROJECT_NAME} CONFIGURATIONS ReleaseARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/lib/ReleaseLIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/lib/ReleaseCONFIGURATIONS DebugRUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/bin/Debug)
则表示执行
cmake --install srcPath --config Debug
命令时,只安装RUNTIME内容,而不安装ARCHIVE和LIBRARY内容。相反的,如果执行
cmake --install srcPath --config Release
命令时,只安装ARCHIVE和LIBRARY内容,而不安装RUNTIME内容。
此外,默认的安装动作和安装配置都是Release的。
1.4 COMPONENT
指定安装的组件名。目前还不确定组件的创建方式,等待后续完善。
1.5 EXCLUDE_FROM_ALL
不安装的内容。
1.6 RENAME
1.7 OPTIONAL
表示此安装命令为可选项,找不到也不会报错。
二、Installing Targets
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> ...]])
1.支持的target
1.1 ARCHIVE
静态库(除了macOS)、dll导入库(也就是dll对应的lib文件)
1.2 LIBRARY
共享库(lib文件,不包括dll文件)
1.3 RUNTIME
可执行文件,dll文件。
1.4 OBJECTS
对象库的对象文件。参考add_library中的object library。
1.5 FRAMEWORK、BUNDLE、PUBLIC_HEADER、PRIVATE_HEADER、RESOURCE
这些都是与apple平台相关的内容,没有环境,不做解释。
其中PUBLIC_HEADER、PRIVATE_HEADER、RESOURCE官文解释非apple平台也有效,但是实际使用时没有反应。
HEADER使用方式:
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER src/hello.h)install(TARGETS ${PROJECT_NAME} PUBLIC_HEADER DESTINATION ${PROJECT_SOURCE_DIR}/include)
2 其他参数
2.1 NAMELINK_COMPONENT、NAMELINK_ONLY、NAMELINK_SKIP
component相关。
2.2 EXPORT
将库名导出,与install(EXPORT)共同作用,将target导出。
2.3 INCLUDES DESTINATION
在执行install(EXPORT)命令进行导出时,将指定目录列表添加到target的属性INTERFACE_INCLUDE_DIRECTORIES中。
最后,对于install(targets)命令而言,一条install可以安装多个target,而一个target也有可能被install多次(都生效,而不是覆盖)。
三、Installing Files
install(<FILES|PROGRAMS> files...TYPE <type> | DESTINATION <dir>[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>][RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
1.FILES | PROGRAMS
两者都是安装文件,只不过FILES安装后的文件默认权限为OWNER_WRITE, OWNER_READ, GROUP_READ和WORLD_READ(如果设置了PERMISSIONS则按PERMISSIONS来);而对PROGRAMS而言,还多了OWNER_EXECUTE, GROUP_EXECUTE和WORLD_EXECUTE三个权限。
安装的文件内容,可以是生成器表达式$<...>,但是以任何表达式开始的文件都要求是完整路径(实际上不是表达式也需要全路径)。
2.TYPE | DESTINATION
两者用于指定文件安装的目标目录,两者不能同事存在。如果使用TYPE的话则会指定文件的类型,并从GNUInstallDirs中获取相应的变量,而如果没有定义此变量则使用内置的默认值。下表则是文件类型对应的变量和默认路径。
| TYPE Argument | GNUInstallDirs Variable | Built-In Default |
| BIN | ${CMAKE_INSTALL_BINDIR} | bin |
| SBIN | ${CMAKE_INSTALL_SBINDIR} | sbin |
| LIB | ${CMAKE_INSTALL_LIBDIR} | lib |
| INCLUDE | ${CMAKE_INSTALL_INCLUDEDIR} | include |
| SYSCONF | ${CMAKE_INSTALL_SYSCONFDIR} | etc |
| SHAREDSTATE | ${CMAKE_INSTALL_SHARESTATEDIR} | com |
| LOCALSTATE | ${CMAKE_INSTALL_LOCALSTATEDIR} | var |
| RUNSTATE | ${CMAKE_INSTALL_RUNSTATEDIR} | <LOCALSTATEdir>/run |
| DATA | ${CMAKE_INSTALL_DATADIR} | <DATAROOTdir> |
| INFO | ${CMAKE_INSTALL_INFODIR} | <DATAROOTdir>/info |
| LOCALE | ${CMAKE_INSTALL_LOCALEDIR} | <DATAROOTdir>/locale |
| MAN | ${CMAKE_INSTALL_MANDIR} | <DATAROOTdir>/man |
| DOC | ${CMAKE_INSTALL_DOCDIR} | <DATAROOTdir>/doc |
如果提供了DESTINATION参数,则使用DESTINATION参数提供的目录。
四、Installing Directories
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...]] [...])
用于安装一个或多个目录到目标目录,目录结构被完整的拷贝。每个目录的最后一项会被添加到目标目录,如果不想这样则可以以/结尾,表示最后一项为空。
#表示将build目录下的内容安装到test目录下
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/
DESTINATION ${PROJECT_SOURCE_DIR}/test)#表示将build目录的内容安装到test目录下
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build
DESTINATION ${PROJECT_SOURCE_DIR}/test)
如果输入目录为空,则创建目标目录,且内容为空。
1.权限
FILE_PERMISSIONS、DIRECTORY_PERMISSIONS 、USE_SOURCE_PERMISSIONS三者用于控制目标目录(DIRECTORY_PERMISSIONS)和文件(FILE_PERMISSIONS)的权限。如果使用了USE_SOURCE_PERMISSIONS,而FILE_PERMISSIONS没有指定,则文件权限与源文件权限一样。
如果没有指定FILE_PERMISSIONS权限,则文件的权限与FILES命令的权限一样(OWNER_WRITE, OWNER_READ, GROUP_READ和WORLD_READ),而目录权限与PROGRAMS一样(OWNER_WRITE, OWNER_READ, GROUP_READ,WORLD_READ,OWNER_EXECUTE, GROUP_EXECUTE和WORLD_EXECUTE)
2.过滤
目录的安装可以通过PATTERN和REGEX选项细粒度的控制,其中PATTERN匹配完整文件名,REGEX默认匹配文件名中的任何一部分(可以通过/或者$实现与PATTERN相同的效果)。
默认情况下,所有文件和目录都会被install(不论PATTERN和REGEX的匹配结果),但是我们可以通过设置FILES_MATCHING过滤没有匹配的文件。
#目录全部拷贝,安装以target开始的文件
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/ DESTINATION ${PROJECT_SOURCE_DIR}/test
FILES_MATCHINGPATTERN "target*")#目录全部拷贝,只安装target文件
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/ DESTINATION ${PROJECT_SOURCE_DIR}/test
FILES_MATCHINGPATTERN "target")#目录全部拷贝,安装文件名包含target的文件
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/ DESTINATION ${PROJECT_SOURCE_DIR}/test
FILES_MATCHINGREGEX "target")#REGEX通过前缀$或后缀/达到与PATTERN相同的效果
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/ DESTINATION ${PROJECT_SOURCE_DIR}/test
FILES_MATCHINGREGEX "target/")
install(DIRECTORY ${PROJECT_SOURCE_DIR}/build/ DESTINATION ${PROJECT_SOURCE_DIR}/test
FILES_MATCHINGREGEX "$target")
五、Installing Exports
install(EXPORT <export-name> DESTINATION <dir>[NAMESPACE <namespace>] [[FILE <name>.cmake]|[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][EXPORT_LINK_INTERFACE_LIBRARIES][COMPONENT <component>][EXCLUDE_FROM_ALL])
生成并安装一个CMake文件,该文件包含了将targets从安装目录中导入到其他项目的代码。安装的内容是跟上面install(TARGETS)中EXPORT的选项一样。
NAMESPACE选项将在目标名被写入导入文件时在前面添加<namespace>。默认生成的文件为<export-name>.cmake,而FILE选项可以将其设置为其他名字,这个名字必须以.cmake结尾。
下面是一个简单的例子:
创建一个项目hello:
cmake_minimum_required(VERSION 3.20)
project(target01 VERSION 1.0.0)
file(GLOB SOURCES "src/*")set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/../helloPkg/)add_library(${PROJECT_NAME} SHARED ${SOURCES})set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER src/hello.h)install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}ARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/../helloPkg/lib/ReleaseRUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/../helloPkg/bin/ReleasePUBLIC_HEADER DESTINATION ${PROJECT_SOURCE_DIR}/../helloPkg/include)# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmakeinstall(EXPORT ${PROJECT_NAME} DESTINATION ${PROJECT_SOURCE_DIR}/../helloPkg/lib/cmake/${PROJECT_NAME}NAMESPACE TEST::)
configure_file(${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.cmake.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmakeDESTINATION ${PROJECT_SOURCE_DIR}/../helloPkg/lib/cmake/${PROJECT_NAME})
同目录下创建src文件夹,并创建:
class __declspec(dllexport) Hello
{
public:void print();
};
#include "hello.h"
#include <iostream>void Hello::print() {std::cout << "hello world!" << std::endl;
}
CMakeLists.txt统计目录下创建target01.cmake.in:
@PACKAGE_INIT@include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@.cmake")
然后在hello同级目录下创建main项目
cmake_minimum_required(VERSION 3.20)
project(main)set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/../helloPkg/lib/cmake)
set(target01_DIR ${PROJECT_SOURCE_DIR}/../helloPkg/lib/cmake/target01/)find_package(target01 REQUIRED PATHS ${PROJECT_SOURCE_DIR}/../helloPkg/)
add_executable(${PROJECT_NAME} src/main.cpp)target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/../helloPkg/include)
target_link_libraries(${PROJECT_NAME} PRIVATE TEST::target01)
创建src目录并创建main.cpp
#include "hello.h"int main()
{Hello h;h.print();return 0;
}
最后,在main项目同级目录下创建helloPkg文件夹。
这里虽然没搞懂中间的configure_file和*.cmake.in文件的作用,但是试出来了,先记一下。
相关文章:
cmake基础(3)——安装
一、简介 install命令用于指定安装时的规则,由于安装命令比较复杂,这里做一部分内容的介绍,后续用到再继续完善。 1.命令简介 本文档基于3.20,目前有6种安装方式。 install(TARGETS <target>... [...]) install({FILES …...
LeetCode解法汇总1572. 矩阵对角线元素的和
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 描述: 给你一个正…...
BFC(Block formatting context 块级格式化上下文)
1、开启了BFC能解决什么问题? 给父元素开启BFC,其子元素不会再产生 margin 塌陷问题。自己不会被其他浮动元素所覆盖。就算其子元素浮动,元素自身高度也不会塌陷。 2、如何开启? 根元素浮动元素绝对定位、固定定位的元素行内块…...
Leetcode-每日一题【剑指 Offer 14- II. 剪绳子 II】
题目 2、3、3的三段,此时得到的最大乘积是18。 答案需要取模 1e97(1000000007),如计算初始结果为:1000000008,请返回 1。 示例 1: 输入: 2输出: 1解释: 2 1 1, 1 1 1 示例 2: 输入: 10输出…...
bye 我的博客网站
Bye🙋🙋🙋,我的博客网站。在我的服务器上运行了9个月之久的博客网站要和大家Bye了。 背景 可能很多人不知道我的这个博客网站的存在,好吧,最后一次展示它了,博客网站地址在这里,它…...
Llama 2:开放基础和微调聊天模型
介绍 大型语言模型(llm)作为高能力的人工智能助手,在复杂的推理任务中表现出色,这些任务需要广泛领域的专家知识,包括编程和创意写作等专业领域。它们可以通过直观的聊天界面与人类进行交互,这在公众中得到了迅速而广泛的采用。 法学硕士的能力是显著的考虑到训练的表面上…...
JVM工作的总体机制概述
JDK、JRE、JVM关系回顾 JVM:Java Virtual Machine,翻译过来是Java虚拟机JRE:Java Runtime Environment,翻译过来是Java运行时环境 JREJVMJava程序运行时所需要的类库JDK:Java Development Kits,翻译过来是…...
jmeter工具测试和压测websocket协议【杭州多测师_王sir】
一、安装JDK配置好环境变量,安装好jmeter 二、下载WebSocketSampler发送请求用的,地址:https://bitbucket.org/pjtr/jmeter-websocket-samplers/downloads/?spma2c4g.11186623.2.15.363f211bH03KeI 下载解压后的jar包放到D:\JMeter\apache-j…...
国产漏洞扫描器Xray入门,详细教程
国产漏洞扫描器Xray入门,详细教程 1.Xray简介2.快速开始3.使用 xray 代理模式进行漏洞扫描4.使用 xray 基础爬虫模式进行漏洞扫描5.使用 xray 进行服务扫描1.Xray简介 xray 是一款功能强大的安全评估工具,由多名经验丰富的一线安全从业者呕心打造而成,主要特性有: 检测速度…...
LeetCode209. 长度最小的子数组
题目:LeetCode209. 长度最小的子数组 描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子…...
css冒号对齐
实现后的样式效果 实现方式 html: <el-col v-if"item.showInSingle ! false" :span"6" style"padding: 4px 0"><label>{{ item.label }}:</label><span v-if"singleData[item.prop] ! 0 &…...
那些年的golang开发经验记录
goland 问题CreateProcess error216, 该版本的 %1 与你运行的 Windows 版本不兼容。请查看计算机的系统信息,然后联系软件发布者 Cannot run program "......" (in directory "D:\project\go\awesomeProject\src\test"): CreateProcess error2…...
element中select下拉框如何实现宽度自适应
简单暴力: element 和 elementPlus 都可以直接在el-select上添加 style"width: 100%" 解决 <el-select style"width: 100%" v-model"cats" multiple filterable placeholder"请选择分类"> . . . </el-select&…...
springboot项目get请求下划线转驼峰@JsonProperty注解失效问题
问题:解决sprigboot项目get请求中有下划线的入参参数,如:first_name,希望在项目中将下划线格式转成firstName,用JsonProperty注解发现失效问题 1.核查:JsonProperty注解对应包是否正确 正确包:…...
架构训练营学习笔记:6-2 微服务基础选型
基础选型 微服务基础设施架构 优先级 其中,核心 就是服务注册、服务发现、服务路由。 模式1-嵌入SDK 模式2-反向代理式 模式3-网络代理式(Service Mesh) 模式对比 常见微服务框架选择 嵌入SDK-dubbo Spring Cloud 反向代理式 APISIX …...
opencv实战项目 实现手势跟踪并返回位置信息(封装调用)
OpenCV 是一个基于 Apache2.0 许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 需要提前准备opencv 和 mediapipe库 pip --default-timeout5000 install -i https://pypi.tuna.tsi…...
ElementUI动态添加表单项
昨天感冒发烧了,脑子不好使。在实现这个动态表单项时一直报错脑瓜子嗡嗡的! 不过好在昨天休息好了,今天起来趁脑瓜子好使,一会就弄好了。 这里记录一下 <el-form-itemv-for"(classId,index) in addFom.classIds":lab…...
Myatis和MybatisPlus常见分页方式
Myatis和MybatisPlus常见分页方式 一、mybaits 原生limit分页 SELECT * FROM order_info limit #{pageNow},#{pageSize}分页插件(ssm中,通过xml配置分页。springboot通过则通过配置文件) PageHelper插件:PageHelper.startPage(…...
利用ChatGPT绘制思维导图——以新能源汽车竞品分析报告为例
随着人们对环境保护的日益关注和传统燃油汽车的限制,全球范围内对新能源汽车的需求不断增长。新能源汽车市场的激烈竞争使得了解各个竞品的特点和优劣成为关键。然而,针对这一领域的详尽竞品分析却常常需要大量时间和精力。 在此背景下,人工智…...
redis集群搭建(非常详细,适合新手)
免密登录脚本 #!/bin/bash # 检查是否已经存在 SSH 密钥对,如果没有则创建一个 if [ ! -f ~/.ssh/id_rsa ]; thenssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N fi# 为每个目标主机复制公钥 for ip in 192.168.9.{11..16}; dossh-copy-id -i ~/.ssh/id_rsa.pub …...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
