tnblog
首页
视频
资源
登录

Cmake 初探

2860人阅读 2024/5/26 17:04 总访问:3456936 评论:0 收藏:0 手机
分类: 传说中的c

Cmake 初探

CMake简介


CMake 是一个开源的、跨平台的构建系统(编译工具),它主要用于管理项目的构建过程。
它通过使用简明的脚本语言来生成适用于不同平台和编译器的构建文件。(可跨平台)

安装CMake


通过执行如下命令的进行安装CMake。

  1. sudo apt install cmake -y
  2. # 查看版本
  3. cmake --version

简单示例


首先创建一个main.c文件的c程序,编写一点简单的代码输出hello word。

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4. printf("Hello World\n");
  5. return 0;
  6. }


CMakeLists.txt 是 CMake(Cross-Platform Make)构建系统中的一个核心文件,它用于定义一个项目的构建过程。
接下来我们在同一目录下创建一个CMakeLists.txt文件,并写入如下内容。

  1. # cmake的最低版本要求是2.8
  2. cmake_minimum_required (VERSION 2.8)
  3. # 工程名
  4. project (demo)
  5. # 由源文件main.c 生成执行文件main
  6. add_executable(main main.c)


然后我们在当前目录中执行如下命令进行编译。

  1. # 自动生成文件有 CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
  2. cmake .
  3. # 编译文件(用已自动生成的Makefile文件)
  4. make
  5. ls


其中main绿色的就是我们的可执行程序

  1. ./main


接下了我们执行清理编译之后的相关程序

  1. # 清楚编译中的生成文件(如 main.o main)
  2. make clean

多文件


重新写main.c代码。

  1. #include <stdio.h>
  2. #include "fun.h"
  3. int main(void)
  4. {
  5. show(10);
  6. return 0;
  7. }


定义fun.h

  1. #ifndef _FUN_H_
  2. #define _FUN_H_
  3. void show(int data);
  4. #endif


定义fun.c

  1. #include <stdio.h>
  2. #include "fun.h"
  3. void show(int data)
  4. {
  5. printf("data is %d\n", data);
  6. }


修改CMakeLists.txt的第一种方式,在add_executable方法中添加相关文件名

  1. # cmake的最低版本要求是2.8
  2. cmake_minimum_required (VERSION 2.8)
  3. # 工程名
  4. project (demo)
  5. # 由源文件main.c 生成执行文件main
  6. add_executable(main main.c fun.c)


第二种,用变量存放编译需要的源文件。

  1. cmake_minimum_required (VERSION 2.8)
  2. # 工程名
  3. project (demo)
  4. # 用变量,存放的文件列表
  5. set( SRC_LIST
  6. ./main.c
  7. ./fun.c
  8. )
  9. # 根据SRC_LIST中的源文件 生成执行文件main
  10. add_executable(main ${SRC_LIST})


源文件很多时,通过指定当前目录的位置进行编译。

  1. cmake_minimum_required (VERSION 2.8)
  2. project (demo)
  3. # 把当前目录下的源文件列表,存放到变量SRC_LIST里
  4. aux_source_directory(. SRC_LIST)
  5. # 根据SRC_LIST中的源文件 生成执行文件main
  6. add_executable(main ${SRC_LIST})

多目录


多目录,还有相同的接口情况下如何解决?

  1. //main.c
  2. #include <stdio.h>
  3. #include "fun.h"
  4. #include "look.h"
  5. int main(void)
  6. {
  7. show(10);
  8. look();
  9. return 0;
  10. }


定义两个目录funlook目录。

  1. // fun.h
  2. #ifndef _FUN_H_
  3. #define _FUN_H_
  4. void show(int data);
  5. #endif
  6. // fun.c
  7. #include <stdio.h>
  8. #include "fun.h"
  9. void show(int data)
  10. {
  11. printf("data is %d\n", data);
  12. }
  1. // look.h
  2. #ifndef _FUN_H_
  3. #define _FUN_H_
  4. void look();
  5. #endif
  6. // look.c
  7. #include <stdio.h>
  8. #include "look.h"
  9. void look()
  10. {
  11. printf("look go\n");
  12. }


修改CMakeLists.txt
通过include_directories的方法指定一个或多个包含目录。
通过aux_source_directory方法用于自动添加一个目录中的所有源文件到一个变量中。

  1. cmake_minimum_required (VERSION 2.8)
  2. project (demo)
  3. # 指定头文件的搜索路径(先fun目录,再look目录)
  4. include_directories (fun look)
  5. # 把fun目录下的源文件列表,存放到变量SRC_LIST_FUN里
  6. aux_source_directory (fun SRC_LIST_FUN)
  7. # 把look目录下的源文件列表,存放到变量SRC_LIST_LOOK里
  8. aux_source_directory (look SRC_LIST_LOOK)
  9. add_executable (main main.c ${SRC_LIST_FUN} ${SRC_LIST_LOOK})

库生成


好处就是源代码我们一般不希望对方看到。
目录结构如下:


其中的fun.cfun.h的内容不变。
添加一个CMakeLists.txt文件,内容如下:

  1. aux_source_directory (. SRC_LIST)
  2. # 根据SRC_LIST的源文件,生成动态库fun_shared
  3. add_library (fun_shared SHARED ${SRC_LIST})
  4. # 根据SRC_LIST的源文件,生成静态库fun_static
  5. add_library (fun_static STATIC ${SRC_LIST})
  6. # 设置库的属性(如输出库名 版本号等)
  7. set_target_properties (fun_shared PROPERTIES OUTPUT_NAME "fun")
  8. set_target_properties (fun_static PROPERTIES OUTPUT_NAME "fun")
  9. #//指定生成的库文件,存放在工程根目录下的lib目录
  10. set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)


修改在learning根目录下的CMakeLists.txt

  1. cmake_minimum_required (VERSION 2.8)
  2. project (demo)
  3. add_subdirectory (fun)


可以看见在lib目录下已经生成了相关的文件

库使用


创建include文件夹将fun/fun.h复制到该目录下。
include成为接口目录。


创建一个新的目录src,并在下面定义main.c文件以及CMakeLists.txt文件。

  1. #include <stdio.h>
  2. #include "fun.h"
  3. int main(void)
  4. {
  5. show(10);
  6. return 0;
  7. }
  1. aux_source_directory (. SRC_LIST)
  2. include_directories (../include)
  3. # 添加非标准的共享库搜索路径
  4. link_directories (${PROJECT_SOURCE_DIR}/lib)
  5. add_executable (main ${SRC_LIST})
  6. # 连接库(默认链接动态库,无则链接静态库,也可指明链接fun.a)
  7. target_link_libraries (main fun)
  8. set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)


修改在根目录下的CMakeLists.txt文件。

  1. cmake_minimum_required (VERSION 2.8)
  2. project (demo)
  3. add_subdirectory (fun)
  4. add_subdirectory (src)

标准结构

  1. //bin 输出的执行文件
  2. //build 存放构建中的中间文件
  3. //lib
  4. libfun.a libfun.so
  5. //CMakeLists.txt cmake的总配置文件
  6. cmake_minimum_required (VERSION 2.8) #// cmake的最低版本要求是2.8,我们安装的是3.10.2
  7. project (demo) #//工程名
  8. add_subdirectory (src) #//添加子目录(自动构建时,会进入src中找 子CMakeLists.txt)
  9. //include/fun.h
  10. #ifndef _FUN_H_
  11. #define _FUN_H_
  12. void show(int data);
  13. #endif
  14. //include/look.h
  15. #ifndef _LOOK_H_
  16. #define _LOOK_H_
  17. void look();
  18. #endif
  19. //src/main.c
  20. #include <stdio.h>
  21. #include "fun.h"
  22. #include "look.h"
  23. int main(void)
  24. {
  25. show(10);
  26. look();
  27. return 0;
  28. }
  29. //src/look.c
  30. #include <stdio.h>
  31. #include "look.h"
  32. void look(void)
  33. {
  34. printf("look go\n");
  35. }
  36. //src/CMakeLists.txt cmake的子配置文件
  37. aux_source_directory (. SRC_LIST) #//把当前目录下的源文件列表,存放到变量SRC_LIST里
  38. include_directories (../include) #//指定 上级目录下的include 为头文件的搜索路径
  39. link_directories (${PROJECT_SOURCE_DIR}/lib) #//添加库搜索路径
  40. add_executable (main ${SRC_LIST}) #//根据SRC_LIST中的源文件 生成执行文件main
  41. target_link_libraries (main fun) #//连接库(默认链接动态库,无则链接静态库,也可指明链接fun.a)
  42. #//设定 执行文件的输出位置 为工程根目录下的bin目录
  43. set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
  44. //构建运行
  45. $ cd build
  46. $ cmake .. //进到build 目录后再cmake构建,避免生成中间文件,污染了工程
  47. $ make
  48. $ cd ../bin //执行文件是输出到 bin
  49. $ ./main

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

初探k8s

概念补充Deployment 是在 Pod 这个抽象上更为上层的一个抽象层,它可以定义一组 Pod 的副本数量,以及这个 Pod 的版本。一...

初探Argo

初探Argo[TOC] 什么是 Argo CD? Argo CD 是 Kubernetes 的声明性 GitOps 持续交付工具。应用程序定义、配置和环境应该是...

BGP RR路由反射与Calico的初探

BGP RR路由反射与Calico的初探[TOC] BGP RR路由反射介绍由于IBGP水平分割的存在,为了保证所有的BGP路由器都能学习到完整...

Flannel CNI初探

Flannel CNI初探[TOC] Flannel 简介Flannel是由CoreOs提出的跨主通信容器网络解决方案,通过分配和管理全局唯一容器IP以及...

python 初探神经网络(一元一次函数)学习笔记

python 初探神经网络(一元一次函数)学习笔记[TOC] B站学习课程 豆豆实验有个小蓝的生物,想吃豆豆,豆豆越大豆豆的毒性...

Outlook WebAddin初探

Outlook WebAddin初探[TOC] 安装前提首先,确保你的计算机上已安装Node.js和npm。你可以在官方网站下载并安装它们。 VS C...

HugginFace 初探

HugginFace 初探[TOC] 安装环境python环境是3.6。import sys sys.version 安装torch,简单起见,避免环境问题,并且计...

Pytorch 初探

Pytorch 初探[TOC] Pytorch简介PyTorch由 Facebook 的 AI 研究团队开发的一个开源的机器学习库,它提供了张量(tensor)计...
这一世以无限游戏为使命!
排名
2
文章
633
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术