栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

学C++从Cmake学起

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

学C++从Cmake学起

文章目录
    • 1.构建系统make
    • 2.构建系统CMake
    • 3.CMake的常见命令行调用
    • 4.CMakeLists.txt常见语法
    • 5.为什么需要库library?
    • 6.CMake 中的静态库与动态库
    • 7.为什么 C++ 需要声明

0:46:55

1.构建系统make 2.构建系统CMake
  • 为了解决make的以上问题,跨平台的Cmake应运而生
  • 只需要写一份CmakeLists.txt,它就能在调用时生成当前系统所支持的构建系统
  • CMake可以自动检测源文件和头文件之间的依赖关系,导出到Makefile里面
  • CMake具有相对高级的语法,内置的函数能够处理configure,install等常见需求
  • CMake可以自动检测当前的编译器,需要添加哪些flag,必须OpenMP,只需要在CMakeLists,txt中指明target_link_libraries(a.out OpenMP::OpenMP_CXX)即可
3.CMake的常见命令行调用
生成构建文件Makefile
表示输出makefile文件的目录
表示试用clang++作为编译器
cmake -Bbuild  -DCMAKE_CXX_COMPILER=clang++
cmake -Bbuild  -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_STANDARD=17

构建可执行文件,编译
cd build;make
或者make -C build,优点是:跨平台
或者cmake --build build
4.CMakeLists.txt常见语法
add_executable(输出的可执行文件 输入的多个源文件)
add_executable(a.out main.cpp hello.cpp)

add_library(test STATIC source1.cpp source2.cpp)  # 生成静态库 libtest.a
add_library(test SHARED source1.cpp source2.cpp)  # 生成动态库 libtest.so

创建库以后,要在某个可执行文件中使用该库,只需要:
target_link_libraries(myexec PUBLIC test)  # 为 myexec 链接刚刚制作的库 libtest.a

5.为什么需要库library?

有时候我们会有多个可执行文件,他们之间用到的某些功能是相同的,我们想把这些共用的功能做成一个库,方便大家一起共享.

  • 静态库和动态库都是多个.o文件的打包
  • 库中的函数可以被可执行文件调用,也可以被其他库文件调用。
  • 库文件又分为静态库文件和动态库文件。
  • 其中静态库相当于直接把代码插入到生成的可执行文件中,会导致体积变大,但是只需要一个文件即可运行.
  • 而动态库则只在生成的可执行文件中生成“插桩”函数,当可执行文件被加载时会读取指定目录中的.dll文件,加载到内存中空闲的位置,并且替换相应的“ 插桩”指向的地址为加载后的地址,这个过程称为重定向。
    这样以后函数被调用就会跳转到动态加载的地址去。
  • eg:以course/01/05/hello.cpp为例:objdump -D ./build/a.out |less
    插装函数puts如下,可跳转到libc.so库中,plt就是插装函数Windows:- 可执行文件同目录,其次是环境变量%PATH%

Linux:

  • ELF格式可执行文件的RPATH,其次是/usr/lib等
6.CMake 中的静态库与动态库

CMake 除了 add_executable 可以生成可执行文件外,还可以通过 add_library 生成库文件。

add_library 的语法与 add_executable 大致相同,除了他需要指定是动态库还是静态库:
add_library(test STATIC source1.cpp source2.cpp)  # 生成静态库 libtest.a
add_library(test SHARED source1.cpp source2.cpp)  # 生成动态库 libtest.so
  • 动态库有很多坑,特别是 Windows 环境下,初学者自己创建库时,建议使用静态库。
  • 创建库以后,要在某个可执行文件中使用该库,只需要:
target_link_libraries(myexec PUBLIC test)  # 为 myexec 链接刚刚制作的库 libtest.a
其中 PUBLIC 的含义稍后会说明(CMake 中有很多这样的大写修饰符)
  • eg:course/01/06
    动态库必须在可执行文件的同目录或者系统目录下,可执行程序才能运行;


    静态库则无所谓,静态库是将实现hello()直接放在a.out中,它不需要动态查找,但是可执行文件会变大
    objdump -D ./build/a.out |less
7.为什么 C++ 需要声明

在多文件编译章中,说到了需要在 main.cpp 声明 hello() 才能引用。为什么?

  • 因为需要知道函数的参数和返回值类型:这样才能支持重载,隐式类型转换等特性。
    例如 show(3),如果声明了 void show(float x),那么编译器知道把 3 转换成 3.0f 才能调用。
  • 让编译器知道 hello 这个名字是一个函数,不是一个变量或者类的名字:这样当我写下 hello() 的时候,他知道我是想调用 hello 这个函数,而不是创建一个叫 hello 的类的对象。

其实,C++ 是一种强烈依赖上下文信息的编程语言,

  • 举个例子:
    vector < MyClass > a; // 声明一个由 MyClass 组成的数组
    如果编译器不知道 vector 是个模板类,那他完全可以把 vector 看做一个变量名,把 < 解释为小于号,从而理解成判断‘vector’这个变量的值是否小于‘MyClass’这个变量的值。
    正因如此,我们常常可以在 C++ 代码中看见这样的写法:typename decay::type
    因为 T 是不确定的,导致编译器无法确定 decay 的 type 是一个类型,还是一个值。
    因此用 typename 修饰来让编译器确信这是一个类型名……

  • 参考:学C++从Cmake学起,PPT和源码地址

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993823.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号