《CMake实践》笔记+实践记录,包括一些书中的坑

这本教程很短,总共只有47页,然而下来共花费约8个小时。其中,阅读+例程实践共花费(3.4日 - 3.10日)共花费5小时21分钟;整理笔记+发博客(3.11日和3.29日)共花费2小时25分钟 。

放一张阅读时间记录图。
阅读时间记录
做笔记总结真的太耗时了,而且自己很抗拒。由上图知,假如说只在文档上做标记,确实很简单,用5天的时间就看完了。然而起后便扔下不管了,直到今天快月底了才不得不写一篇总结,努力往上爬真他妈难啊。。。。

阅读完的时候,自己的任务也就结束了,可这样总感觉不是自己的东西,不如整理一下,吸收其中自己认为最有用的东西,这样也能极大的减轻自己的记忆负担。

当然,与自己使用marddown语法不熟练和MarkdownPad 2这个软件不好用也有关系,导致自己排版也花费了好多精力,下次直接在csdn里的markdown记录就行了,不要用MarkdownPad 2,别人觉得好用了不一定适合自己!!!

记笔记的教训总结一下:

  1. 最后总结的时候,不要事无巨细都想记录下来。只记录自己觉得最有用的就行了,想象如果只让你记录三点你会记录哪些,以此来帮助自己筛选重要的东西。
  2. 工具用好,以后就在csdn里面记录了,统一工具也避免不必要的麻烦!

笔记从第三章开始,包括一些文档里的错误所造成的坑!

三 初试 cmake – cmake 的 helloworld

遇到的坑
不要直接复制原文中代码,原文中代码""用的是中文字符,所以编译会出错,而且不好发现

  1. cmake … 之后make

     首先注意的是,当你定义了工程名时,cmake会预定义一些带有工程名的cmake变量。
     PROJECT (HELLO)  
     HELLO_BINARY_DIR   HELLO_SOURCE_DIR  PROJECT_BINARY_DIR    PROJECT_SOURCE_DIR  
     如果是内部编译,就相当于 PROJECT_SOURCE_DIR 也就是
     工程代码所在目录,如果是外部编译,**指的是外部编译所在目录**  
    
  2. 指令是大小写无关的,参数和变量是大小写相关的 ; IF中使用变量名,不需要${变量名}

  3. 清理工程 make clean

  4. 内部构建和外部构建,cmake强烈推荐的是外部构建(out-of-source build)

     内部构建就是在工程主目录下,也就是CMakeLists.txt所在的文件夹下编译;
    
     而外部构建不是在此目录下编译的。一般是新建一个build文件夹,在此文件夹下cmake ..,生成makefile文件,然后再make编译。
    

四 更好一点的 Hello World

工程中多了src目录存放源文件。

  1. 需要为任何子目录建立一个 CMakeLists.txt
    PROJECT(HELLO)
    ADD_SUBDIRECTORY(src bin)
    应该把这两条指令写在工程的 CMakeLists.txt 还是 src 目录下的CMakeLists.txt?
    把握一个简单的原则,在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY,
    如果需要改变目标存放路径,就在哪里加入上述的定义

  2. 如何安装文件
    如果你希望使用 CMAKE_INSTALL_PREFIX 来定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是
    ${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>。
    安装的需要有两种,一种是从代码编译后直接 make install 安装,一种是打包时的指定目录安装。

     make和make install 的区别:  
     make是在本地编译,编译所产生的文件在编译的文件夹里;  
     make install则把编译产生的文件(如库文件,可执行文件,以及cmake指定的要安装的文件)安装到某个目录(一般是系统目录),这样其他程序就可以调用编译的这些东西了。  
    

    安装需要这个变量:CMAKE_INSTALL_PREFIX ,格式如下:
    cmake -DCMAKE_INSTALL_PREFIX=/usr .
    即生成安装到/usr目录的make file

  3. INSTALL一共有如下几种形式:

    1. 目标文件的安装:
      INSTALL(TARGETS targets... [ARCHIVE|LIBRARY|RUNTIME] [DESTINATION dirname] [PERMISSIONS permissions...] [...])
      INSTALL(TARGETS myrun mylib mystaticlib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION libstatic )
      可执行二进制 myrun 安装到 C M A K E I N S T A L L P R E F I X / b i n 目 录 动 态 库 l i b m y l i b 安 装 到 {CMAKE_INSTALL_PREFIX}/bin 目录 动态库 libmylib 安装到 CMAKEINSTALLPREFIX/binlibmylib{CMAKE_INSTALL_PREFIX}/lib 目录
      静态库 libmystaticlib 安装到${CMAKE_INSTALL_PREFIX}/libstatic 目录
      特别注意的是你不需要关心 TARGETS 具体生成的路径,只需要写上 TARGETS 名称就可以
      了。
    2. 普通文件的安装
      INSTALL(FILES files... DESTINATION <dir> [PERMISSIONS permissions...])
      非目标文件的可执行程序安装(比如脚本之类):
      INSTALL(PROGRAMS files... DESTINATION <dir> [PERMISSIONS permissions...])
      脚本安装后注意设置权限为:
      OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限
    3. 目录的安装
      INSTALL(DIRECTORY dirs... DESTINATION <dir> [FILE_PERMISSIONS permissions...])
      DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意:
      abc 和 abc/有很大的区别。
      如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾,
      代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
    4. 安装时CMAKE脚本的执行:
      INSTALL([[SCRIPT <file>] [CODE <code>]] [...])

五 静态库与动态库构建

本章主要讲了如何编译动态库/静态库,并安装库文件与头文件(.h)到系统目录中,以便其他程序调用这个库.
动态库是 .so文件,又叫共享库,静态库是.a文件。

  • 如何通过 ADD_LIBRARY 指令构建动态库和静态库;
  • 如何通过 SET_TARGET_PROPERTIES 同时构建同名的动态库和静态库;
  • 如何通过 SET_TARGET_PROPERTIES 控制动态库版本;
  • 最后将头文件和共享库安装到系统目录/usr/lib 和/usr/include/hello

所有的添加目录操作ADD_SUBDIRECTORY(lib)都在最外层的CMakeLists.txt中添加,且目录都是相对最外层的,不是绝对路径。

六 如何使用外部共享库和头文件

main.c中包含头文件hello.h会失败,因为hello.h 位于/usr/include/hello 目录中,并没有位于系统标准的头文件路径(系统标准头文件路径在/usr/include,其子目录hello并不是)

#include <hello.h>
int main()
{
HelloFunc();
return 0;
}

所以需要引入头文件搜索路径
INCLUDE_DIRECTORIES(/usr/include/hello)
此时编译还是会失败,因为没有链接到hello库文件。
所以需为 target 添加共享库
讲了两个指令
LINK_DIRECTORIES(directory1 directory2 ...)
添加非标准的共享库搜索路径,这个对应上面的INCLUDE_DIRECTORIES,本例没有用到此指令。
TARGET_LINK_LIBRARIES(main hello)

七 cmake 常用变量和常用环境变量

需要注意cmake变量分为隐式定义和显式定义两种。可以理解为隐式变量就是cmake自动生成的,直接可以用的。
隐式定义如PROJECT 指令,他
会隐式的定义_BINARY_DIR 和_SOURCE_DIR 两个变
量。显式定义如 SET 指令,就可以构建一个自定义变量了。

八 cmake 常用指令

主要讲了基本指令,INSTALL指令,FIND_指令(如FIND_FILE,FIND_LIBRARY,FIND_PATH,FIND_PACKAGE)

  1. 基本指令
    ADD_DEPENDENCIES,定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。
    CMAKE_MINIMUM_REQUIRED
    比如 CMAKE_MINIMUM_REQUIRED(VERSION 2.5 FATAL_ERROR)
    如果 cmake 版本小与 2.5,则出现严重错误,整个过程中止。
  2. FIND指令
    找到目标之后都会存到VAR变量里面。
    FIND_FILE( name1 path1 path2 …)
    FIND_LIBRARY( name1 path1 path2 …)
    FIND_PATH( name1 path1 path2 …)
    FIND_PROGRAM( name1 path1 path2 …)
    FIND_PACKAGE()

九 复杂的例子:模块的使用和自定义模块

FIND_PACKAGE(CURL)
这句指令会自动产生一些变量,如CURL_FOUND CURL_INCLUDE_DIR CURL_LIBRARY,每一个模块都会定义以下几个变量:

  • _FOUND
  • _INCLUDE_DIR or _INCLUDES
  • _LIBRARY or _LIBRARIES

FIND_PACKAGE([package name] REQUIRED) REQUIRED 参数,其含义是指这个共享库是否是工程必须的,如果使用了这个参数,说明这个链接库是必备库,如果找不到这个链接库,则工程不能编译。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CMake是一个跨平台的构建工具,它可以用于创建、测试和打包软件项目。使用CMake可以简化构建过程,提高开发效率。 首先,CMake具有平台无关性,可以在不同的操作系统上运行。它使用一种简单的语法来描述项目的构建过程,而不依赖于特定的编译器或构建系统。这意味着你可以使用相同的CMake配置文件在不同的平台上构建项目,而无需修改代码。 其次,CMake支持模块化的项目组织。可以将项目分割成多个模块,每个模块包含一个独立的CMake配置文件。这样可以使得项目更加清晰,易于维护。而且,CMake还支持库的编译和链接,可以将常用的功能封装成库,在不同的项目中共享使用。 另外,CMake支持多种编译选项和构建类型。你可以根据不同的需求,选择合适的编译器和编译选项,进行不同类型的构建。例如,可以选择优化选项进行发布构建,选择调试选项进行调试。 此外,CMake还支持外部依赖库的管理。可以在CMake配置文件中指定项目所依赖的外部库,并自动下载和安装这些库。这样可以提高项目的可移植性和可维护性。 最后,CMake提供了丰富的文档和社区支持。CMake官方网站提供了详细的文档和教程,以及常见问题的解答。而且,CMake社区活跃,有很多开发者和用户可以提供支持和帮助。 总之,CMake是一个功能强大、易用且跨平台的构建工具,可以帮助开发者简化项目的构建过程,提高开发效率。在实践中,我们可以利用CMake来管理项目的构建,提高代码的可维护性和可移植性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值