CMake中add_library的使用

news2024/12/23 0:30:22

      CMake中的add_library命令用于使用指定的源文件向项目(project)中添加库,其格式如下:

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...]) # Normal Libraries
add_library(<name> OBJECT [<source>...]) # Object Libraries
add_library(<name> INTERFACE) # Interface Libraries
add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL]) # 3.19 version, Interface Libraries
add_library(<name> <type> IMPORTED [GLOBAL]) # Imported Libraries
add_library(<name> ALIAS <target>) # Alias Libraries

      1.Normal Libraries:添加一个名为<name>的库目标(library target),从命令调用中列出的源文件构建。<name>对应于逻辑目标名称,并且在项目中必须是全局唯一(globally unique)的。构建的库的实际文件名是基于本机平台(native platform)的约定构建的(例如lib<name>.a或<name>.lib).
      add_library的源参数可以使用语法为$<...>的"generator expressions".
      如果后面使用target_sources命令添加源文件,则可以省略它们。
      可以给出STATIC,SHARED或MODULE来指定要创建的库的类型。STATIC库是链接其它目标时使用的目标文件存档(archive of object file).SHARED库是动态链接的,并在运行时加载。MODULE库是未链接到其它目标但可以在运行时使用类似dlopen的功能动态加载的插件。如果没有明确给出类型,则根据变量BUILD_SHARED_LIBS的当前值是否为ON,来决定类型是STATIC还是SHARED。对于SHARED和MODULE库,POSITION_INDEPENDENT_CODE目标属性自动设置为ON。可以使用FRAMEWORK目标属性标记SHARED库以创建macOS Framework。
      可以使用FRAMEWORK目标属性标记STATIC库以创建static Framework。
      如果库不导出任何符号,则不得将其声明为SHARED库。例如,不导出非托管符号(exports no unmanaged symbols)的Windows资源DLL需要是MODULE库。CMake期望SHARED库在Windows上始终具有关联的导入库(import library).
      默认情况下,库文件将在与调用命令的源树目录对应的构建树目录中创建(the library file will be created in the build tree directory corresponding to the source tree directory in which the command was invoked)。可通过ARCHIVE_OUTPUT_DIRECTORY, LIBRARY_OUTPUT_DIRECTORY和RUNTIME_OUTPUT_DIRECTORY目标属性更改此位置。可通过OUTPUT_NAME目标属性更改最终文件名的<name>。
      如果给定了EXCLUDE_FROM_ALL,则将在创建的目标上设置相应的属性。

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_library(add_static STATIC ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp) # 将会在build目录下生成libadd_static.a
if(TARGET add_static)
    message("target: static library add") # print
endif()

add_library(add_shared SHARED ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp) # 将会在build目录下生成libadd_shared.so
if(TARGET add_shared)
    message("target: shared library add") # print
endif()

add_library(add_module MODULE ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp) # 将会在build目录下生成libadd_module.so
if(TARGET add_module)
    message("target: module library add") # print
endif()

      2.Object Libraries:创建对象库(Object Library).对象库编译源文件,但不会将其存档或链接到库中。相反,由add_library命令或add_executable命令创建的其它目标可以使用$<TARGET_OBJECTS:objlib>形式的表达式作为源来引用对象,其中objlib是对象库名称。
      可以使用target_link_libraries命令链接对象库。

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(add_object OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp) # 在build目录下不会有add_object文件生成
if(TARGET add_object)
    message("target: object library add") # print
endif()

      3.Interface Libraries:创建接口库(Interface Library).INTERFACE库目标不编译源代码,也不在磁盘上生成库文件。但是,它可能设置了属性,并且可以安装和导出。通常,使用以下命令在接口目标上填充INTERFACE_*属性:然后它像任何其它目标一样被用作target_link_libraries命令的参数

set_property(),
target_link_libraries(INTERFACE),
target_link_options(INTERFACE),
target_include_directories(INTERFACE),
target_compile_options(INTERFACE),
target_compile_definitions(INTERFACE),
target_sources(INTERFACE),

      使用上述签名创建的接口库本身没有源文件,并且不作为目标包含在生成的构建系统中。
      接口库可以具有PUBLIC_HEADER和PRIVATE_HEADER属性。可以使用install(TARGETS)命令安装由这些属性指定的headers。
      3.19版本中,可以使用源文件创建接口库。源文件可以直接在add_library调用中列出,也可以稍后通过使用PRIVATE或PUBLIC关机键调用target_sources添加。
      如果接口库有源文件(即设置了SOURCES目标属性)或头文件集(即设置了HEADER_SETS目标属性),它将作为构建目标出现在生成的构建系统中,就像add_custom_target命令。它不编译任何源代码,但包含由add_custom_command命令创建的自定义命令的构建规则。
      注意:在大多数出现INTERFACE关键字的命令签名中,其后列出的项仅成为该目标使用要求的一部分,而不是目标自身设置的一部分。但是在add_library的签名中,INTERFACE关键字仅指库类型。在add_library调用中列出的源是接口库的PRIVATE,不会出现在其INTERFACE_SOURCES目标属性中。

add_library(add_interface INTERFACE) # 在build目录下不会有add_interface文件生成
if(TARGET add_interface)
    message("target: interface library add") # print
endif()

      4.Imported Libraries:创建一个名为<name>的IMPORTED库目标。不会生成任何规则来构建它,并且IMPORTED目标属性为True。目标名称在创建它的目录及其下的目录中具有作用域(has scope),但是GLOBAL选项扩展了可见性。它可以像项目中构建的任何目标一样被引用。IMPORTED库可用于方便地从target_link_libraries等命令中引用。通过设置名称以IMPORTED_和INTERFACE_开头的属性来指定有关导入库的详细信息。
      <type>必须是以下之一:
      (1).STATIC, SHARED, MODULE, UNKNOWN:引用位于项目外部的库文件。IMPORTED_LOCATION目标属性(或其每个配置变量)指定磁盘上主库文件(main library)的位置:
      对于大多数非Windows平台上的SHARED库,主库文件是链接器和动态加载器使用的.so或.dylib文件。
      对于Windows上的SHARED库,IMPORTED_IMPLIB目标属性(或其每个配置变量IMPORTED_IMPLIB_<CONFIG>)指定DLL导入库文件(.lib或.dll.a)在磁盘上的位置。IMPORTED_LOCATION是.dll运行时库的位置。
      可以在INTERFACE_*属性中指定其它使用要求。
      UNKNOWN库类型通常仅用于Find Modules的实现。它允许使用导入库的路径(通常使用find_library命令找到),而不必知道它是什么类型的库。这在Windows上特别有用,静态库和DLL导入库具有相同的文件扩展名。
      (2).OBJECT:引用位于项目外部的目标文件。IMPORTED_OBJECTS目标属性(或其每个配置变量IMPORTED_OBJECTS_<CONFIG>)指定目标文件在磁盘上的位置。可以在INTERFACE_*属性中指定其它使用要求。
      (3).INTERFACE:不引用磁盘上的任何库或目标文件,但可以在INTERFACE_*属性中指定使用要求。

add_library(add_imported SHARED IMPORTED) # 在build目录下不会有add_imported文件生成
if(TARGET add_imported)
    message("target: imported library add") # print
endif()

      5.Alias Libraries:创建一个别名目标(Alias Target),以便<name>可用于在后续的命令中引用<target>。<name>不会作为make目标出现在所生成的构建系统中。<target>可能不是ALIAS。
      An ALIAS can target a GLOBAL Imported Target.
      An ALIAS can target a non-GLOBAL Imported Target.这种别名的作用域是创建它的目录和子目录。ALIAS_GLOBAL目标属性可以用来检查别名是不是全局的。
      ALIAS目标可以用作可链接的目标,也可以用作从中读取属性的目标。也可以使用常规的if(TARGET)子命令测试它们是否存在。<name>不能用来修改<target>的属性,即,它不能用作set_property, set_target_properties,target_link_libraries等命令的操作数。ALIAS目标不能被安装或导出

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(add_alias ${CMAKE_CURRENT_SOURCE_DIR}/source/subtraction.cpp)
add_library(yyyy ALIAS add_alias)
if(TARGET yyyy)
    message("target: yyyy") # print
endif()
if(TARGET add_alias)
    message("target: add_alias") # print
endif()

      执行测试代码需要多个文件

      build.sh内容如下:

#! /bin/bash

# supported input parameters(cmake commands)
params=(function macro cmake_parse_arguments \
		find_library find_path find_file find_program find_package \
		cmake_policy cmake_minimum_required project include \
		string list set foreach message option if while return \
		math file configure_file \
		include_directories add_executable add_library target_link_libraries install)

usage()
{
	echo "Error: $0 needs to have an input parameter"

	echo "supported input parameters:"
	for param in ${params[@]}; do
		echo "  $0 ${param}"
	done

	exit -1
}

if [ $# != 1 ]; then
	usage
fi

flag=0
for param in ${params[@]}; do
	if [ $1 == ${param} ]; then
		flag=1
		break
	fi
done

if [ ${flag} == 0 ]; then
	echo "Error: parameter \"$1\" is not supported"
	usage
	exit -1
fi

if [[ ! -d "build" ]]; then
	mkdir build
	cd build
else
	cd build
fi

echo "==== test $1 ===="

# test_set.cmake: cmake -DTEST_CMAKE_FEATURE=$1 --log-level=verbose ..
# test_option.cmake: cmake -DTEST_CMAKE_FEATURE=$1 -DBUILD_PYTORCH=ON ..
cmake -DTEST_CMAKE_FEATURE=$1 ..
# It can be executed directly on the terminal, no need to execute build.sh, for example: cmake -P test_set.cmake
make
# make install # only used in cmake files with install command

      CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.22)
project(cmake_feature_usage)

message("#### current cmake version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}")
include(test_${TEST_CMAKE_FEATURE}.cmake)
message("==== test finish ====")

      test_add_library.cmake内容为上面的所有测试代码段。

      另外还包括三个目录:include,source,samples,它们都是非常简单的实现,仅用于测试,如下:

        可能的执行结果如下图所示:

      GitHub: https://github.com/fengbingchun/Linux_Code_Test

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

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

相关文章

【Java 快速复习】垃圾回收算法 垃圾回收器

快速理解 Java 垃圾回收算法 & 垃圾回收器 先说个关系概念&#xff0c;垃圾回收的算法是逻辑概念的定义&#xff0c;用于规范垃圾回收器实现方的一些行为&#xff0c;而垃圾回收器就是实现这些算法的工具&#xff0c;这些工具大概是一系列的 C 的类以及其实现的一些对应回…

Linux服务器上跑深度学习实验

原文地址&#xff1a;Linux上跑深度学习实验 目录远程连接环境搭建与服务器断开连接后代码停止之前一直使用Google Colab跑实验&#xff0c;因为实验的规模不大&#xff0c;配合Google Drive用起来就很舒服&#xff0c;但是最近要系统地进行实验&#xff0c;规模一下子上来了&a…

【Spring】一文带你搞懂Spring容器配置

前言 本文为大家介绍的是Spring容器配置相关知识&#xff0c;包含Bean和Configuration的使用&#xff0c;使用 AnnotationConfigApplicationContext实例化Spring容器&#xff0c;Bean注解的使用&#xff0c;Configuration的使用&#xff0c;Import 注解的使用&#xff0c;结合J…

C++中STL-set详解

目录 set/ multiset容器 1. set基本概念 2.set构造和赋值 3.set大小和交换 4.set插入和删除 5.set容器-查找和统计 6.set和multiset的区别 7.pair对组创建 8.set容器排序 9.set存放自定义数据类型 set/ multiset容器 1. set基本概念 简介: 所有元素都会在插入时自动…

使用Apisix打造家庭NAS网关,免公网IP访问

使用Apisix打造家庭NAS网关 本文使用apisix打造家庭NAS网关&#xff0c;并通过cloudflare进行穿透&#xff0c;可免公网IP访问。首先你的NAS支持Docker&#xff0c;没有NAS也没有关系&#xff0c;只要你的电脑支持Docker同样可以参照该教程。 1 依赖资源准备 准备域名: 免费…

HTML+CSS+JS做一个好看的个人网页—web网页设计作业

个人网页设计个人网页&#xff08;htmlcssjs&#xff09;——网页设计作业带背景音乐&#xff08;The way I still Love you&#xff09;、樱花飘落效果、粒子飘落效果页面美观&#xff0c;样式精美涉及&#xff08;htmlcssjs&#xff09;&#xff0c;下载后可以根据自己需求进…

8086,8088CPU管脚,奇偶地址体, 时钟信号发生器8284 ,ready信号,reset复位信号。规则字和非规则字

8086/8088均为40条引线&#xff0c;双列直插式封装&#xff0c;某些引线有多重功能&#xff0c;其功能转换有两种情况&#xff1a;一种是分时复用&#xff0c;一种是按组态定义。 用8088微处理器构成系统时&#xff0c;有两种不同的组态&#xff1a; 最小组态&#xff1a;808…

模型效果不好?推荐你8种机器学习调参技巧

大家好&#xff0c;今天给大家一篇关于机器学习调参技巧的文章 超参数调优是机器学习例程中的基本步骤之一。该方法也称为超参数优化&#xff0c;需要搜索超参数的最佳配置以实现最佳性能。 机器学习算法需要用户定义的输入来实现准确性和通用性之间的平衡。这个过程称为超参…

嵌入式开发学习之--RCC(上)

提示&#xff1a;本篇主要介绍一下不同时钟的特性和作用&#xff0c;了解为主。 文章目录前言一、RCC简介二、系统时钟简介2.1HSE 高速外部时钟信号2.2锁相环 PLL2.3系统时钟 SYSCLK2.4AHB 总线时钟 HCLK2.5 APB2 总线时钟 HCLK22.6 APB1 总线时钟 HCLK1三、其他时钟3.1RTC 时钟…

HTTP 请求是什么?

文章目录HTTP请求一&#xff0c;请求行二&#xff0c;请求头三&#xff0c;空行四&#xff0c;请求体五&#xff0c;HTTP请求示例HTTP请求 请求是由客户端向服务器发送的&#xff0c;一般可以分为请求行、请求头、空行和请求体四个部分&#xff0c;如下图所示&#xff1a; 一…

【数据集NO.2】工业检测数据集汇总(缺陷、纹理等检测)

文章目录前言一、东北大学钢材表面缺陷数据集二、天池铝型材表面缺陷数据集三、Severstal 带钢缺陷数据集四、UCI 带钢缺陷数据集五、磁瓦缺陷数据集六、RSDDs铁轨表面缺陷数据集七、印刷电路板&#xff08;PCB&#xff09;瑕疵数据集八、坑洼检测数据集九、Kylberg纹理检测十、…

C语言:文件操作(1)

1、什么是文件&#xff1f; 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文件有两种: 程序文件、数据文件 程序文件&#xff1a; 包括源程序文件(后缀为.c)&#xff0c;目标文件(windows环境后缀为.obj)&#xff0c;可执行程序(wndows环境后缀为.exe) 数…

初级测试到中级测试就差这几个找bug小技巧

前言 测试的过程就是一个寻找影响产品功能和用户体验bug的过程&#xff0c;测试人员发现的bug类型五花八门。 当你在上班期间&#xff0c;听到不远处传来这样的声音“你会不会提BUG&#xff0c;责任人都指派错了&#xff0c;还能好好提吗&#xff1f;” 如果哪天开发对着你说…

Babel自动生成Attribute文档实现详解

这篇文章主要为大家介绍了Babel自动生成Attribute文档实现示例详解&#xff0c;有需要的朋友可以借鉴参考下&#xff0c;希望能够有所帮助&#xff01; 1. 前言 利用Babel自动解析源码属性上的注释生成对应Markdown文档&#xff0c;这个场景的应用主要包括在组件库文档对组件…

SpringBoot单元测试

文章目录1、什么是单元测试2、单元测试有哪些好处&#xff1f;3、SpringBoot 单元测试使用3.1 生成单元测试的类3.2 配置单元测试的类并添加SpringBootTest注解3.3 添加单元测试的业务代码3.4 进行测试并查看结果3.5 使用断言3.6 在不修改数据库的前提下&#xff0c;执行单元测…

室内温度控制仿真模型(Simulink+PLC)

本篇博客将会和大家一起一步步解读Simulink自带的仿真模型(Thermal Model of a House),之后再讨论PLC控制系统控制环境温度的一些经验方法。温度控制的大部分控制方法都是采用PID控制,有关PLC的PID控制相关内容可以参看专栏的其它文章,链接如下: 博途PLC 1200/1500PID P…

【LeetCode每日一题:1774. 最接近目标价格的甜点成本~~~递归+深度优先遍历】

题目描述 你打算做甜点&#xff0c;现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则&#xff1a; 必须选择 一种 冰激凌基料。 可以添加 一种或多种 配料&#xff0c;也可以不添加任何配料。 每种类型的配料 最多两份 。 给你…

java计算机毕业设计ssm人事考勤管理系统1u133(附源码、数据库)

java计算机毕业设计ssm人事考勤管理系统1u133&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…

Spread 16.X FOR WPF 中文版 我就喜欢 Spread.NET

Spread 16.X FOR WPF 中文版您可以将 Microsoft Excel 的强大功能嵌入到 WPF 和 Silverlight 应用中&#xff0c;使用丰富的内嵌数据可视化功能展现核心数据和分析结果&#xff0c;按需自定制富有创意的表格模版以及发挥更多便捷高效的功能。Spread WPF-Silverlight 源自备受好…

RIoTBoard开发板系列笔记(十三)—— yocto SDK安装与使用

yocto是一个很强大的嵌入式image 构建工具&#xff0c;借助yocto可以轻松的构建出一个开发板镜像。如果我们想借助yocto开发一些应用层的程序&#xff0c;有以下两种方法可供选择&#xff1a; &#xff08;1&#xff09;按照yocto的构建规则添加自己的程序和编译脚步&#xff0…