01.从CMake讲起

CMake:将cpp源文件编译为exe文件、

常见的编译器:

动态链接库

-o文件是临时对象文件(预编译),生成了汇编文件


Make软件:只用写出不同文件之间的以来关系,和生成各文件的规则。

>make a.out
·敲下这个命令,就可以构建出a.out这个可执行文件了。
·和直接用一个脚本写出完整的构建过程相比,make指明依賴关系的好处:
1.当更新了cpp时只会重新编译cpp.o,而不需要把其他main.o也重新编译一遍。
2.能够自动并行地发起对he№℃pp和main℃pp的编译,加快编译速度(make-j)。
3.用通配符批量生成构建规则,避免针对每个℃pp和囤重复写g++命令(%,0:%.cpp)。
但坏处也很明显:

1.make在Unix类系统上是通用的,但在Windows则不然。
2.需要准确地指明每个顺目之间的依賴关系,有头文件时特别头疼。
3.make的语法非常简单,不像shell或python可以做很多判断等。
4.不同的编译器有不同的flag规则,为g++准备的爹数可能对MSVC不适用。


CMake:

你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。CMake 就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等 [1]。在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:

·读取当前目录的CMakeLists.txt,并在build文件夹下生成build/Makefile:
·>cmake -B build
·让make读取 build/Makefile,并开始构建a.out:
·>make -C build
·以下命令和上一个等价,但更跨平台:
·>cmake--build build
·执行生成的a.out:
·>build/a.out
 


库(Library):

·有时候我们会有多个可执行文件,他们之间用到的某些功能是相同的,我们想把这些共用
的功能做成一个库,方便大家一起共享。
·库中的函数可以被可执行文件调用,也可以被其他库文件调用。
·库文件又分为静态库文件(和单文件作为库来链接类似)和动态库文件。


其中静态库相当于直接把代码插入到生成的可执行文件中,会导致体积变大,但是只需要
一个文件即可运行。(类似于内联)


而动态库则只在生成的可执行文件中生成“插桩”函数,当可执行文件被加载时会读取指
定目录中的.dll文件,加载到内存中空闲的位置,并且替换相应的“插桩”指向的地址为加
载后的地址,这个过程称为重定向。这样以后函数被调用就会跳转到动态加载的地址去。节省可执行文件大小和运行时内存。

lib中存到就是插桩函数


Windows:可执行文件同目录,其次是环境变量%PATH%
·Linux:ELF格式可执行文件的RPATH,其次是/usr/iib等
 

CMake中的静态库与动态库
·CMake除了add_executable可以生成可执行文件外,还可以通过add_library生成库文件。
.add_libiary的语法与add_executable大致相同,除了他需要指定是动态库还是静态库:
·add_library(test STATC source1.cpp source2.cpp) #生成静态库libtest.a
·add_library(test SHARED source1.cpp source2.cpp) #生成动态库libtest.so
·动态库有很多坑,特别是Windows环境下,初学者自己创建库时,建议使用静态库
·但是他人提供的库,大多是作为动态库的
·创建库以后,要在某个可执行文件中使用该库,只需要:
·target_link_libraries(myexec PUBILC test)  #为myexec链接刚刚制作的库libtest.a

动态库需要在运行时在同目录或系统目录找到对应lib文件,才能运行.


头文件:


预处理器:实质将#include替换为头文件中的内容,类似于高级语言中的模块,但因为其全部替换,较为低效。

<>会防止引入当前目录文件(例如一些垃圾文件)

在头文件前加#pragma once,保证改头文件只被引用一次。


CMake中的子模块:

·复杂的工程中,我们需要划分子模块,通常一个库一个目录,比如:


.这里我们把hellolib库的东西移到hellolib文件夹下了,里面的CMakeLists.txt定义了
hellolib的生成规则。
·要在根目录使用他,可以用CMake的add_subdirectory添加子目录,子目录也包含一个
CMakeLists.txt,其中定义的库在add_subdirectory之后就可以在外面使用。

·因为hello、h被移到了hellolib子文件夹里,因此main、cpp里也要改成:
.如果要避免修改代码,我们可以通过target—include—directories指定a.out的头文件搜索目录:(其中第一个hellolib是名,第二个是目录)

 

·这样甚至可以用<hello.h>来用这个头文件了,因为通过target-include_directories指定的路径被视为与系统路径等价

·但是这样如果另一个b.out也需要用hellolib这个库,难道也得再指定一遍搜索路径吗?
.不需要,其实我们只需要定义hellolib的头文件搜索路径,引用他的可执行文件CMake会
自动添加这个路径:

·这里用了·表示当前路径,因为子目录里的路径是相对路径,类似还有灬表示上一层目录。
·此外,如果不希望让引用hellolib的可执行文件自动添加这个路径,把PUBL℃改成
PRIVATE即可。这就是他们的用途:决定一个属性要不要在被link的时候传播。
 


第三方库

1.纯头文件库

.有时候我们不满足于C++标准库的功能,免会用到一些第三方库。
.最友好的一类库莫过于纯头文件库了,这里是一些好用的header-only库:

1.nothings/stb.大名鼎鼎的stb_image系列,涵盖图像,声音,字体箐,只需单头文件!
2.Neargye/magic—enum-枚举类型的皮射,如枚举转字符串箐(实现方式很巧妙)
3.g-truc/glm-仿GLSL语法的数学矢量/矩阵库(附带一些常用函数,随机数生成箐)
4.Tencent/rapidjson-单纯的JSON库,甚至没依賴STL(可定制性高,工程美学经典)
5.ericniebler/range-v3-C++20ranges库就是受到他启发(完全是头文件组成)
6.fmtlib/fmt-相式化库,提供std::format的替代品(需要-DFMT_HEADER_ONLY)
7.gabime/spdlog-能适配控制台,安卓等多后端的日志库(和fmt冲突!)

只需要把他们的include目录或头文件下载下来,然后include_directories(spdlog/include)即可。
·缺点:函数直接实现在头文件里,没有提前编译,从而需要重复编译同样内容,编译时间长。

valarray C++98就引入了标准库,可以类似于numpy

glm数学库:很好用的库


2.作为子模块引入

·第二友好的方式则是作为CMake子模块引入,也就是通过add_subdirectoryø
·方法就是把那个I页目(以fmt为例)的源码放到你工程的根目录:
·这些库能够很好地支持作为子模块引入:
1.fmtlib/fmt-格式化库,提供std::format的替代品
2.gabime/spdlog-能适配控制台,安卓等多后端的日志库
3.ericniebler/range-v3,C++20ranges厍就是受到他启发
4.g-truc/glm-仿GLSL语法的数学矢量/矩阵库
5.abseil/abseil-cpp -旨在补充标准库没有的常用功能
6.bombela/backward-cpp-实现了C++的堆栈回溯便于调试
7.google,/googletest-谷单元测试框架
8.google/benchmark·谷歌性能评估框架
9.glfw/glfw OpenGL窗口和上下文管理
10.libigl/libigl 各种图形学算法大合集


3.引入系统中预安装的第三方库
 

包管理器:windows无自带的包管理器,可以下载vcpck

现代CMake认为一个包可以提供多个库,又称组件

以下是bilibili课程视频:

【录播】现代C++中的高性能并行编程与优化(持续更新中)_哔哩哔哩_bilibili

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CMake项目中,可以使用`cmake ..`命令来指定使用的CMake文件。具体来说,可以通过在项目的根目录下创建一个名为`CMakeLists.txt`的文件来定义项目的构建规则和配置选项。然后,在项目的构建目录中运行`cmake ..`命令,CMake会自动查找并使用根目录下的`CMakeLists.txt`文件来进行项目的构建。 如果你想使用自定义的CMake文件,可以按照以下步骤进行操作: 1. 在项目的根目录下创建一个名为`Findxxx.cmake`的文件,其中`xxx`是你自定义的文件名。 2. 在`Findxxx.cmake`文件中编写你需要的CMake命令,例如定义变量或函数等。 3. 在主`CMakeLists.txt`文件中使用`include`命令将`Findxxx.cmake`文件引入,以便在项目中使用其中定义的变量或函数。 以下是一个示例,演示了如何使用自定义的`Findxxx.cmake`文件: 1. 创建`FindMyLibrary.cmake`文件,并在其中定义一个变量`MY_LIBRARY_PATH`: ```cmake set(MY_LIBRARY_PATH "/path/to/my/library") ``` 2. 在主`CMakeLists.txt`文件中使用`include`命令引入`FindMyLibrary.cmake`文件,并使用其中定义的变量: ```cmake include(FindMyLibrary.cmake) # 使用MY_LIBRARY_PATH变量 message("My library path: ${MY_LIBRARY_PATH}") ``` 当你运行`cmake ..`命令时,CMake会自动查找并使用`CMakeLists.txt`文件,并在其中使用`include`命令引入`FindMyLibrary.cmake`文件。然后,你可以在项目中使用`MY_LIBRARY_PATH`变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值