学习Opencv(蝴蝶书/C++)相关——2.用clang++或g++命令行编译程序

2023-11-08 16:01

本文主要是介绍学习Opencv(蝴蝶书/C++)相关——2.用clang++或g++命令行编译程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1. c/cpp程序的执行
    • 1.1 cpp程序的编译过程
    • 1.2 预处理指令
    • 1.3 编译过程的细节
  • 2. macOS下使用Clang看cpp程序的编译过程
    • 2.1 示例
      • 2.1.1 第一步 预处理器-preprocessor
      • 2.1.2 第二步 编译器-compiler
      • 2.1.3 第三步 汇编器-assembler
      • 2.1.4 第四步 链接器-linker
      • 2.1.5 链接其他源文件
    • 2.2 Clang的常见命令语法
      • 2.2.1 常见使用
      • 2.2.2 文档
    • 2.3 GCC, LLVM,CLang以及MSVC
  • 3. 使用clang或者gcc执行使用了OpenCV库的程序
    • 3.1 手动链接需要的库
    • 3.2 参数说明
    • 3.3 当前opencv含有的链接库
      • 3.3.1 在clang命令中使用pkg-config --libs opencv来链接库
      • 3.3.2 配置pkg-config --libs opencv
    • 3.4 `-I,-L,-l`与visual studio中的对应
  • 4. object program,动态链接库和静态链接库等的区别
    • 4.1 编译生成的目标文件和动态链接库,静态链接库的区别
    • 4.2 动态链接库和静态链接库的区别

非常建议去看一下B站这个课程:基于VSCode和CMake实现C/C++开发 | Linux篇:
就是讲在不使用Visual Studio这种IDE的情况下,纯靠g++/gcc这样的命令行去逐步执行cpp程序的编译,链接,执行等操作。

另外,也可以看一下这篇文章,都有助于理解用编译器的命令行去执行cpp程序:
MacOS使用clang

1. c/cpp程序的执行

1.1 cpp程序的编译过程

这里复习一下本科的知识,

  1. 编译程序把高级语言写的源程序(source program,比如:.cpp后缀)转换为机器指令的目标程序(object program,比如:.o后缀)
  2. 编译时是以源程序文件(即.c或者.cpp)为对象进行的,分别对每个源程序文件进行编译得到相应的目标程序,再将这些目标程序链接成为一个统一的二进制的可执行程序。
  3. 预处理指令和C++语句分开处理,前者由预处理器(或者也常称为预编译器)对预处理指令(#开头的,比如宏定义和include)进行预处理,详见 1.2 预处理指令
  4. 把预处理得到的结果和程序剩下的部分一起,组成一个完整的,可以用来编译的最终的源程序,编译程序对该源程序正式进行编译,得到目标程序。
  5. 不同的编译系统除了会提供C/CPP规定的标准库函数外,有些编译系统还会提供自己的专门的函数/库函数。

C/CPP的编译过程:

图自:什么是动态链接与静态链接?
在这里插入图片描述

  1. 编译自动包括预编译和正式编译两个阶段,编译得到本源文件的目标文件(Windows下一般是.obj的后缀,UNIX下一般是.o的后缀)。
  2. 再通过链接把所有需要的目标文件链接在一起,就得到了最后的可执行程序(Executive program,Windows下一般是.exe的后缀,UNIX下一般没有后缀)
    • 即便程序只有一个源程序文件(一个X.cpp),编译后得到的目标函数也不能直接运行,也需要经过连接阶段,因为要与库函数链接,才能生成可执行程序。

参考:

  • 【本质】你知道C语言编译的过程吗?
  • C语言程序设计-谭浩强
  • Introduction to C/C++ compilation in Linux os with gcc
  • The C++ Compilation Model

1.2 预处理指令

  • #include<iostream>这句话并不是C++语句,而是C++的一个预处理指令,以#开头与常规的C++语句相区别,行的末尾没有分号。
  • #include<iostream>是个包含指令,将iostream文件的内容包含到该命令所在的程序文件中,代替该指令。
  • 由于这类指令都放在程序开头,因此称为"头文件"(header file)
  • 编译时,先对所有的预处理命令进行处理,将头文件的具体内容替换#include指令,然后再对该程序单元进行整体编译。

1.3 编译过程的细节

这个属于编译原理的内容了,可以看看 Alfred V. Aho,Monica S.Lam的编译原理,这里大概放个图:
在这里插入图片描述
代码的编译过程可以分为预处理,词法分析,语法分析,语义分析,目标代码,链接,生成可执行程序。

2. macOS下使用Clang看cpp程序的编译过程

2.1 示例

如果想看gcc的,可以看 【本质】你知道C语言编译的过程吗?这篇文章。

以下内容,大部分出自:MacOS使用clang

编译用的clang_demo.cpp 源码

#include <iostream>
#define STR "Hello world"int main(int argc, const char * argv[]) {std::string a = STR;std::cout << a << std::endl;return 0;
}

查看编译步骤:
(由于是cpp语言,因此用clang++,就好像gcc命令是c语言,g++就是cpp一样)

> clang++ -ccc-print-phases clang_demo.cpp
0: input, "clang_demo.cpp", c++
1: preprocessor, {0}, c++-cpp-output
2: compiler, {1}, ir
3: backend, {2}, assembler
4: assembler, {3}, object
5: linker, {4}, image
6: bind-arch, "x86_64", {5}, image

可以看到,分为6步:

0.输入c++源码程序
1.预处理器,0是输入,输出是把`#`等包含指令解开后的cpp代码
2.编译器, 1是输入, 输出是中间代码IR(intermediate representation)
3.后端,   2是输入,输出是汇编代码
4.汇编器, 

这篇关于学习Opencv(蝴蝶书/C++)相关——2.用clang++或g++命令行编译程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/370954

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基