cmake 生成exe调用生成的lib(动态库与静态库)

2023-10-29

上一个cmake生成exe的博客已经说明了怎么在 linux cmake-gui 和 visual studio 下怎么编译CMake工程。这篇文章会直接在 visual studio 下构建目标。

下面主要对CMake生成的两种方式进行相关的生成

1.总CMakeLists.txt生成所有目标

2.含有subject CMake 生成所有目标

为什么提上面两种方式?这里牵扯到lib构建顺序依赖的问题(这里将在本文的 sub模块分离式生成目标 下进行详细的解释)

 

顶层CMakeLists.txt生成所有目标。

工程结构

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.0)
# 最低版本要求 cmake 构建工具小于2.8.0将报错

project(genExeLinkLib)
# 工程项目名称

#set(MOD_CLASS_PATH "${CMAKE_SOURCE_DIR}/class")
set(MOD_CLASS_PATH ${CMAKE_SOURCE_DIR}/class)
# 设置一个变量标记路径 以上两种写法都是可行的 为了更好的适应各种CMake工程 推荐写第二种方式
# ${CMAKE_SOURCE_DIR} 这个取CMake自带宏里面的路径 就是这个CMakeLists.txt所在的路径

aux_source_directory(${MOD_CLASS_PATH} MOD_CLASS_SRC)
# ${} 固定的范式,取变量 MOD_CLASS_PATH 里面的值,这里为 ${CMAKE_SOURCE_DIR}/class
# MOD_CLASS_SRC 自定义的一个变量
# 整条语句将对 ${CMAKE_SOURCE_DIR}/class 的源码*.cpp 和*.c 文件 输出到变量 MOD_CLASS_SRC

#add_library(class_sayHello ${MOD_CLASS_SRC})# 默认构建静态库
#add_library(class_sayHello STATIC ${MOD_CLASS_SRC}) #和上面语句是一样的 
add_library(class_sayHello SHARED ${MOD_CLASS_SRC}) # 构建动态库
# 将所有的源文件归档成lib 这一句将会在build下生成lib
# 设置生成目录这里暂时先不做编写 如果生成静态库的话直接注释打开然后注释 SHARED 这一句

# --------------上面的语句就已经能够生成动态库------------------
aux_source_directory(${CMAKE_SOURCE_DIR} RP_ALL_SRC)
# 这里对 ${CMAKE_SOURCE_DIR} 也就是当前CMakeList.txt 目录下的*.cpp输出到变量
# RP_ALL_SRC (ROOTPATH_ALL_SRC 意为顶层目录所有源码)
add_executable(HelloExecute ${RP_ALL_SRC})

# --------------这里很明显还没有引用lib 这是至少百分之八十友友遇到的错误----------
# error:link 多半就是目录问题 引用未定义的函数一般都是 宏 或者你忘记写函数实现
target_link_libraries(HelloExecute class_sayHello)  
#为生成目标添加一个库 可以是多个 比如 target_link_libraries(HelloExecute lib1 lib2) 
#这里因为是在同一个CMakeLists.txt中 所以lib会被识别并找到,这里默认构建了其生成的依赖关系
#为了屏蔽平台差异 我们直接省略后缀 .lib  因为gcc生成的库 .a  .so

Hello.h

#ifndef HELLO_H
#define HELLO_H

#include <iostream>

class _declspec(dllexport)  Hello
{
public:
	Hello();
	~Hello();
	void sayHello();
}; 

#endif // !HELLO_H

Hello.cpp

#include "Hello.h"

Hello::Hello()
{
}

Hello::~Hello()
{
}

void Hello::sayHello()
{
	std::cout << __FUNCTION__ << std::endl;
}

main.cpp

#include "class/Hello.h"
#include <iostream>
int main(int argc, char* argv[]) 
{
	Hello helloUnit;
	helloUnit.sayHello();

	int a;
	std::cin >> a;
}

运行结果

 

add_subdirectory生成目标

 

上图对整个目录结构进行梳理,每一个存在CMakeLists.txt 都可以称之为模块。为了更好的实现上图的结构应当避免模块间的耦合度(当然这不是硬性的规定)。具体的模块间的引用问题这里暂时留在下一篇博客中去说明。比如在其他子项的目录中我存在一种顺序依赖的关系、包括后面在 CMakeLists.txt中的 package_find() 语法命令。其实上面的目录结构是存在问题的,这里为了适应本博文和读者理解,循序渐进吧。

 

工程结构:

 

genExeLinkLib/class/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.0) #cmake的 最低版本

project(class)#尽量和目录同名,为了方便区分

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} class_ALL_SRC)
# 遍历当前cmake下的所有*.c和*.cpp文件 输入到变量 class_ALL_SRC
# CMAKE_CURRENT_SOURCE_DIR 是当前的CMakeLists.txt的路径,如果存在疑问你可以打开下面的语句论证
# message(STATUS "CMAKE_CURRENT_SOURCE_DIR >>${CMAKE_CURRENT_SOURCE_DIR}")

add_library(${CMAKE_PROJECT_NAME} ${class_ALL_SRC})
#引用当前所有c和cpp文件 生成一个 class.lib
#CMAKE_PROJECT_NAME 为cmake自带变量 获取当前project()设置的变量,主要作用于当前CMakeLists.txt文件

genExeLinkLib/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.0)

project(genExeLinkLib) #工程名称

aux_source_directory(${CMAKE_CURRENT_LIST_DIR} genXX_ALL_SRC) #遍历当前CMakeLists.txt所有*.c和*.cpp 输出到 genXX_ALL_SRC 变量

add_subdirectory(class) #添加子项

add_executable(genExeLinkLib ${genXX_ALL_SRC}) # 生成可执行目标 genExeLinkLib

target_link_libraries(genExeLinkLib class) # 添加lib依赖

install(TARGETS genExeLinkLib
    RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/dll
	ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
	LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)#安装目录

 

运行结果:

 

 

如果大家在使用CMakeLists.txt工程上遇到了问题可以加我的 CMake技术交流Q群 870836798

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake 生成exe调用生成的lib(动态库与静态库) 的相关文章

  • 来自库的 CMake link_directories

    我正在尝试使用 CMake 和 Xcode 从另一个库链接到一个库 这对任何图书馆来说都是一个问题 但为了让事情更容易传达 让我们使用zlib举个例子 这似乎适用于可执行文件 如下所示 LINK DIRECTORIES LIB DIR zl
  • cmake 不会在更改时重建 externalProject

    我有以下 CMakeLists txt cmake minimum required VERSION 3 0 project addProject include ExternalProject set ExternalProjectCMa
  • 在 Android Studio 中使用预构建的共享库

    我需要在我的 android 项目中使用自定义的预构建共享库 在独立 ndk 上构建为 libdynamic so 我在路径 src main 中创建了一个文件夹 jniLibs 然后在其中创建了 4 个文件夹 即 armeabi arme
  • target_link_libraries 和 INCLUDE_DIRECTORIES 属性

    在这个片段中 cmake minimum required VERSION 3 0 project hello LANGUAGES C VERSION 0 0 1 add library a INTERFACE target include
  • 是否可以使用 gold 链接器编译和链接 Clang/LLVM?

    我正在为 LLVM Clang 编写自定义通道 重新编译往往需要一段时间并使用大量内存 我听说 gold 链接器 1 比标准 ld 链接器花费更少的时间并且 2 使用更少的内存 有没有办法将标志传递到 LLVM Clang 构建过程并更改为
  • 如何在 Windows 下使用 cmake 生成使用 Intel 编译器的 Visual Studio 项目

    我正在用 C 开发一个跨平台 Linux Windows 应用程序 我已经厌倦了维护可用的 Makefile 和 Visual Studio 解决方案 项目 所以我想过渡到 cmake 我在两个平台上都使用英特尔编译器 我在 Windows
  • 具有许多第三方依赖项的大型跨平台 C++ 项目在磁盘上的物理布局

    我正在重新组织物理 磁盘上 布局大型跨平台 C 项目 https github com jupiter jazz appleseed具有许多第三方依赖项 使用 CMake 构建 由于我们需要支持 Windows 这个平台上没有完善的包管理器
  • CMake:用于Android交叉编译的FIND_PACKAGE(Threads)

    我正在使用 Android NDK 和 Cmake 生成项目的共享库 我正在将现有项目从 Ubuntu 移植到 Android 现在我需要移植一些可执行文件 我成功编译了所有需要的可执行文件Threads图书馆 在CMakeList txt
  • ubuntu:升级软件(cmake)-版本消歧(本地编译)[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的机器上安装了 cmake 2 8 0 来自 ubuntu 软件包 二进制文件放置在 usr bin cmake 中 我需要将 cmake 版本至少
  • 使用 NDK 构建具有适用于 Android 的 cmake 构建文件的 C++ 项目

    我必须构建 2 个独立的 C 项目 它们具有针对不同平台的 Cmake 构建文件设置 我想使用 NDK 为 Android 构建它们 以便我可以将它们用作 Android Studio 中的预构建库 如何使用 NDK 为 Android 构
  • CMake:如何最好地构建多个(可选)子项目?

    想象一个包含多个组件的整体项目 basic io web app a app b app c 现在 假设 web 依赖于 io 而 io 又依赖于 basic 所有这些东西都在一个存储库中 并且有一个 CMakeLists txt 将它们构
  • CMake 中 LINK_LIBRARIES 的递归列表

    我正在尝试获取链接到 CMake 中特定目标的所有库的绝对路径列表 以便在调用中使用add custom command 然而 get target property LINK LIBRARIES TARGET LINK LIBRARIES
  • CLion - 命令行程序参数

    当我分配给 运行 调试配置 程序参数 之类的 aaa bbb 然后打印它时 任何人都可以告诉我 JetBrains CLion 有什么问题吗 printf s n argv 1 我刚刚得到 aaa 而它必须是 aaa bbb 因为它们用双引
  • Haskell 项目可以使用 cmake 吗?

    我正在计划一个用 Haskell 编写的项目 也许也有一些部分是用 C 编写的 对于构建系统 我决定不选择 Haskell 程序 cabal 的常见选择 主要是因为我想了解其他语言的构建程序是如何工作的 我听说过 CMake 我认为这是一个
  • 在cmake中,什么是“项目”?

    这个问题是关于project命令 推而广之 是什么concept of a project意思是cmake中的 我真的不明白什么是project是 以及它与target 我想我确实理解 我看了一下cmake 文档project http w
  • 安装 EXPORT 需要子项目中的目标

    我正在尝试编写一个 cmake 脚本来安装我正在处理的项目 其中一部分是必要的install EXPORT LIB EXPORTS where LIB EXPORTS是我在各种项目中一直使用的 EXPORT 属性install TARGET
  • 在生成器表达式中使用 cmake 选项

    我想在生成器表达式中使用 cmake 选项 为了打开某个编译标志 来自文档 https cmake org cmake help v3 10 manual cmake generator expressions 7 html我不清楚如何实现
  • 如何使我的单元测试适应 cmake 和 ctest?

    到目前为止 我已经使用了一个临时的单元测试程序 基本上是由批处理文件自动运行的全部单元测试程序 尽管其中很多都明确地检查了他们的结果 但还有更多的作弊行为 他们将结果转储到版本控制的文本文件中 测试结果中的任何更改都会被颠覆标记 我可以轻松
  • 在cmake中集成bash测试脚本

    我有一个 C cmake 项目 它使用 Boost Test 进行单元测试 现在我想向 cmake 公开一系列 bash 脚本 用于集成测试 假设每个脚本在以下情况下返回 0PASS或某些情况下 0FAILURE 我希望每次运行时都执行每个
  • 使用 CMake 时如何导出 Emscripten 中的 C 函数

    In 本教程 https emscripten org docs porting connecting cpp and javascript Interacting with code html interacting with code

随机推荐

  • 企业运维经典面试题汇总(4)

    1 如何过滤出已知当前目录下yangwen中的所有一级目录 提示 不包含yangwen目录下面目录的子目录及隐藏目录 即只能是一级目录 解答 方法1 通过find直接查找指定类型的文件 root yangwen find yangwen t
  • MP中批量删除,增加,修改实际执行的sql语句

    code GetMapping getNameUpdate public String getNameUpdate RequestBody Map
  • CTF-web 第十三部分 命令注入

    一 基本原理 命令注入指的是 利用没有验证过的恶意命令或代码 对网站或服务器进行渗透攻击 注入有很多种 并不仅仅只有SQL注入 比如 命令注入 Command Injection Eval 注入 Eval Injection 客户端脚本攻击
  • Java 线程池的异常处理机制 错误使用submit导致异常被吞掉,导致UncaughtExceptionHandler不生效

    提交线程池的任务出了异常会怎么样 任务本身出现异常时会怎样呢 我们来看一个例子 提交 10 个任务到线程池异步处理 第 5 个任务抛出一个 RuntimeException 每个任务完成后都会输出一行日志 GetMapping execut
  • CentOS下pdf阅读器

    最初用的是foxit Reader 但用了一段时间感觉CentOS下的foxit Reader真的不太好用 比如 1 每次打开一个PDF文件的时候 既不能自动最大化显示 也不能自动恢复到上次关闭时窗口的大小状态 而只是显示一个非常小的窗口
  • 一个系统测试的完整过程

    转载自http www 51testing com html 68 n 3724968 html 一 需求审查方面 首先我们从最开始接触的文档开始 那就是测需求文档 需求审查主要是我们对需求文档的理解 并熟透整个系统的每个功能和流程 对后期
  • 威联通NAS(QNAP)采用HybridMount挂载百度云网盘

    威联通之前一直不支持挂载百度云网盘 但最近更新了1 9 3761版本的HybridMount 发现已经支持了 下面简要介绍其设置过程 功能介绍 完成设置后 可以从威联通的File Station访问百度云帐户 还可以访问通过SMB NFS
  • qt获取文件 图片大小

    https www it1352 com 1270326 html int size 0 QFile myFile 图片路径 if myFile open QIODevice ReadOnly size myFile size myFile
  • Java获取部门组织树

    本文章记录两种方式获取部门树型结构 一 使用mybatis 因循环查库 比较耗时 二 递归查询 一 使用mybatis实现 1 编写实体类 TreeVO java Data public class TreeVO private Strin
  • Multi-modal Text Recognition Networks: Interactive Enhancements between Visual and Semantic组会

    文本识别网络不断地进步 从单纯地只利用视觉信息到现在的大多数网络都开始结合语义信息 因此现在的文本识别网络可以分为两个部分 分别是VM和LM 那么目前的VM和LM结合的方法可以总结为以下四类 VM之后接LM VM和LM输出的特征结合之后作为
  • jsp脚本案例错误修正

    标题在练习jsp脚本案例中 新建第三个jsp File时 位置变成了这样 代码是正确的 但是运行结果报错 然后把test3 jspmove到WEB INF文件夹下就可以运行正常 运行结果
  • 【Django】创建用户,中间件,表单组件

    HTTP无状态协议 是指协议对于交互性场景没有记忆能力 每次客户端检索网页时 客户端打开一个单独的连接到 Web 服务器 服务器会自动不保留之前客户端请求的任何记录 创建用户对象的三种方法 create 创建一个普通用户 密码是明文的 cr
  • 网络原理笔记一

    文章目录 1 局域网 LAN 2 广域网 WAN 3 网络通信基础 1 IP地址 2 端口号 3 认识协议 4 协议分层 1 网络模型 2 网络数据传输的基本流程 1 局域网 LAN 局域网全称 Local Area Network 局域网
  • 可做毕设/基于opencv的手势识别完整项目/python3.9/万字长文手把手带你学

    可做毕设 基于OpenCV的手势识别 python3 9 前言 正文 图片获取与处理 特征提取 模型训练 界面设计 后语 前言 在一切的开始前 我想先感谢 Brielleqqqqqqjie 大神 没有ta三年前的文章指导 这个小作品一路的学
  • 超详细Vue实现导航栏绑定内容锚点+滚动动画

  • Allure美化测试报告

    1 1 Allure介绍 Allure是一款轻量级并且非常灵活的开源测试报告框架 它支持绝大多数测试框架 例如TestNG Pytest JUint等 它简单易用 易于集成 1 2 Allure下载 到git上下载指定版本的Allure G
  • 标准IO--fgets()

    函数原型 char fgets char s int size FILE stream 参数 s 字符型指针 指向存储读入数据的内存缓冲区的首地址 1 char s 100 2 char s char malloc 100 sizeof c
  • SpringBoot-自定义配置-覆盖自动配置

    Spring Boot 不是有很牛逼的自动配置吗 而且它的牛叉之一就是自动配置 让工程师从繁琐的 重复的配置中解放出来 为什么还要自定义配置 Maven中的中打开pom xml 增加如下配置
  • Pytorch Dataloader 详解

    用 Pytorch 框架训练深度学习模型 怎么能避得开 Dataloader 的使用呢 这个类的各个参数是什么意思 如何用好 Dataloader 本文的初衷 就是试着去回答这些问题 基本设置 dataset torch Dataset 子
  • cmake 生成exe调用生成的lib(动态库与静态库)

    上一个cmake生成exe的博客已经说明了怎么在 linux cmake gui 和 visual studio 下怎么编译CMake工程 这篇文章会直接在 visual studio 下构建目标 下面主要对CMake生成的两种方式进行相关