关于Windows下C/C++的编译

文章目录

  • 关于Windows下C/C++的编译
    • 一、前提
      • (一)预处理
      • (二)编译
      • (三)汇编
      • (四)链接
    • 二、使用clang命令
      • (一)包含外部的头文件
      • (二)包含外部的静态库
      • (三)连接静态库
        • 1.代码中链接
        • 2.编译时命令行链接
      • (四)包含动态库

一、前提

  在C/C++C/C++C/C++编译器中,我们编译程序的过程主要分成以下四个阶段。

  • 预处理
  • 编译
  • 汇编
  • 链接

  具体的实现过程是按照以下的方式来进行的。接下来我们以clangclangclang这个编译器为例,以及test.cpptest.cpptest.cpp这个文件为源文件完成对以上过程的理解。

(一)预处理

  这一阶段的过程主要是对包含源代码的文本文件进行处理。主要的处理内容就是将在源文件中包含的头文件加载到文件中,替换宏定义等等。最终生成的文件是以.i.i.i结尾的文本文件。

clang++ -E test.cpp -o test.i

(二)编译

  这个阶段是将预处理得到的文件经由编译器变成汇编语言。汇编语言中的每一条语句都以一种标准的文本格式准确的描述一条地址机器指令。在这个阶段生成的文件才是机器相关的代码。这个阶段生成以.s.s.s结尾的汇编文本文件。

clang++ -S test.i -o test.s

(三)汇编

  这个阶段就是将上一步得到的汇编文件汇编成机器指令,从而把这些指令打包成为一种可重定向的目标程序格式。这个时候生成以.o​.o​.o​结尾的二进制文件。

clang++ -c test.s -o test.o

(四)链接

  这个阶段主要是处理在文件中调用了系统库例如cincincin等函数,那么就需要将系统库中的cin.ocin.ocin.o合并到我们生成的test.otest.otest.o中。生成可执行的以结尾的.exe.exe.exe二进制文件。

clang++ test.o -o test.exe

二、使用clang命令

  了解了以上的编译过程之后,就有人产生疑问了,那么为什么我们在通常进行编译的时候采用的命令只有以下的一行:

clang++ test.cpp -o test.exe

  其实,clangclangclang早已经将我们以上的四个步骤全部整合为以上的一条命令。这样就使得我们在进行编译的时候不必要生成过多的对运行没有意义的文件。只有在有需求的时候我们才去生成指定文件。

(一)包含外部的头文件

  这个问题其实是在我的一个项目中用到的。在那个项目中我需要使用到opencvopencvopencv这个外部库。可是网上一搜全部是以vsvsvs或者其他的IDEIDEIDE为载体来完成的。这对于我这种不喜欢繁重编译器的人来说这简直就是折磨。于是我自己在命令行配置了opencvopencvopencv并成功运行。

  那么我们现在说一说关于怎样包含外部库。其实很简单,假设我们在编写opencvopencvopencv的时候,需要用到一个opencv.hppopencv.hppopencv.hpp的库,但是这个库并不在我们的标准库文件中。我们需要做的仅仅是在编译的时候在clangclangclang后加上一个参数就好。如下:

clang++ --help
>>  -I <dir>                Add directory to include search path
// opencv.cpp
#include <opencv/opencv.hpp>
...

  假设我们的以上包含的目录在D:/opencv/build/includeD:/opencv/build/includeD:/opencv/build/include里,那么我们的编译命令变成了:

clang++ opencv.cpp -o opencv.exe -I D:/opencv/build/include

(二)包含外部的静态库

  在windowswindowswindows中,静态库是以.lib.lib.lib结尾的文件。有时候我们编译生成的文件也是需要使用到的。那么怎么将外部的libliblib文件连接到我们的目标文件中呢?

  我们仍然是借助clangclangclang的helphelphelp功能:

clang++ --help
>>  -L <dir>                Add directory to library search path

  那么我们完全可以使用以下的命令对原来的数据进行编译:

  假设我们的libliblib文件在以下的文件夹D:/opencv/build/x64/vs15/libD:/opencv/build/x64/vs15/libD:/opencv/build/x64/vs15/lib当中。

clang++ opencv.cpp -o test.exe -I D:/opencv/build/include -L D:/opencv/build/x64/vs15/lib

(三)连接静态库

  到现在为止,我们静态库已经包含完成,但是怎么链接呢,这是个问题,因为不进行链接的话就无法完成外部库中函数的调用。会产生类似于以下的报错:

connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_init,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_options,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_real_connect,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_error,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_query,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_use_result,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_fetch_row,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_num_fields,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_free_result,该符号在函数 main 中被引用
connect-bd0e58.o : error LNK2019: 无法解析的外部符号 mysql_close,该符号在函数 main 中被引用

  也就是说会产生无法解析的外部符号的错,这就表明我们只是将数据包含进来,但是并没有链接成功。我们需要对其进行链接操作。对于静态库的链接有以下两种方式:

1.代码中链接

  代码中链接是采用预处理的方式:

#pragma comment(lib, "libmysql")

  这样就能实现链接到静态库的作用。

2.编译时命令行链接

  编译时链接静态库方法就是,−l-l−l就加静态库名字。

clang++ opencv.cpp -o test.exe -I D:/opencv/build/include -L D:/opencv/build/x64/vs15/lib -llibmysql

  这样就完成了对静态库的链接。

(四)包含动态库

  在windowswindowswindows下,动态库一般是以.dll.dll.dll结尾的文件。那么怎样包含呢?实际上如果不包含动态库,在之前的各个阶段都不会有问题。因为动态库是运行时才用得到的库。因此在GUIGUIGUI界面中,往往会提示你缺少动态库请重新安装后使用。但是在命令行下就十分的狡猾,他甚至不提示任何东西,代码一行也不执行!甚至连最简单的写在mainmainmain函数的第一行的输出helloworldhello\quad worldhelloworld都不执行。而且表面上看起来没有任何异常。随之就程序结束了。我昨天在这个上吃了很多亏。因此需要注意的就是将libliblib文件夹中的dlldlldll文件复制到自己windowswindowswindows下的这两个目录之下就可以运行了。

C:\Windows\System32
C:\Windows\SysWOW64

  以上,送给一个像我一样,爱装逼又爱折腾的你!

关于Clang的编译使用相关推荐

  1. LLVM Clang前端编译与调试

    LLVM Clang前端编译与调试 iOS 关于编译 o 一.Objective-C 编译过程 o 为什么需要重新编译? o 编译步骤 o 二.编译步骤的详细说明 o 1.预处理 o 2.编译 o 词 ...

  2. 编译时如何看到每个文件的编译选项_导出 Clang 可视化编译耗时分析报告 —— ftimetrace 的使用...

    前言 笔者最近加入了新的团队,开始负责编译打包相关工作,因而开始学习优化编译时间相关技术.讲真,蛮开心的,每天都有挑战,同时每天都有收获,天天都在涨姿势,所以想记录下来并分享出来,也方便以后自己需要时 ...

  3. 深入剖析 iOS 编译 Clang LLVM(编译流程)

    2019独角兽企业重金招聘Python工程师标准>>> 前言 iOS 开发中 Objective-C 和 Swift 都用的是 Clang / LLVM 来编译的.LLVM是一个模块 ...

  4. clang编译c语言,clang没有编译c程序?

    在c中编程时,我使用clang编译大部分时间.突然它停止了工作.每当我尝试编译某些内容时,它都会给我这个输出 假设文件名是test.c clang test.c In file included fr ...

  5. (三)Clang/ LLVM编译流程简述

    LLVM概述 LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time).链接时间(link-time).运行时间(r ...

  6. iOS之LLVM编译流程和Clang插件开发集成

    LLVM 简介 一.什么是 LLVM? LLVM 是构架编译器(compiler)的框架系统,以 C++ 编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time).链接时间(l ...

  7. iOS底层探索(二) - 写给小白看的Clang编译过程原理

    iOS底层探索(一) - 从零开始认识Clang与LLVM 写在前面 编译器是属于底层知识,在日常开发中少有涉及,但在我的印象中,越接近底层是越需要编程基本功,也是越复杂的.但要想提升技术却始终绕不开 ...

  8. Clang Static Analyzer 系列(一)编译 Clang 及运行 Checker

    编译 Clang CSA (Clang Static Analyzer) 是 clang 的一部分.建议使用自行编译的 clang ,源码在 llvm/llvm-project (github.com ...

  9. C语言编译器之二,Clang

    二.Clang编译器 Clang编译器是由APPLE公司的编译器大牛Chris Lattner主导下编写的,其目标是替换大名鼎鼎的GCC编译器: 2.1.Clang和GCC编译器架构 从源代码到可执行 ...

最新文章

  1. Oracle10g.CentOS6安装
  2. 【青少年编程】【蓝桥杯】绘制莲花图形
  3. 大神整理的python资源大全
  4. C++中.lib静态库、.dll动态库的生成及调用1
  5. 万网与阿里巴巴业务关系图解
  6. 如何快速解决腿抽筋?
  7. 华为手机怎样才算激活了_外观专利到底怎样才算侵权呢?
  8. 机器学习(1)——基础概念
  9. 路灯干扰者视频2021-08-10
  10. GIS应用知识解读!
  11. 解决面部毛孔粗大的7个小窍门 - 健康程序员,至尚生活!
  12. 人工智能产品经理知识体系和学习计划
  13. iOS企业应用分发平台搭建(uniapp打包)
  14. 数据分析实战平台分享
  15. 《信息安全工程师教程》学习笔记01(第一章)
  16. SpringMVC 13. RESTful CRUD
  17. 计算机技术中的多媒体是什么,在多媒体计算机技术中,媒体含义一般指()。A中介B介质C信息的载体D存储介质 - 试题答案网问答...
  18. bootstrap editable
  19. 《分布式服务框架原理与实践》读书笔记
  20. IO控制器 IO控制方式(程序直接控制、中断驱动、DMA方式、通道控制方式)

热门文章

  1. 车道线检测|利用边缘检测的原理对车道线图片进行识别
  2. 增广贤文--中华蒙学经典
  3. 亲宝宝完成第五次融资 为何如此受资本青睐?
  4. 豆豆趣事[2014年03月]
  5. 万维考试系统题库python_万维考试系统-C语言题库-程序设计题导出-113道
  6. oracle-01031+linux,linux – Oracle返回错误ORA-01031:权限不足
  7. 电容式触摸芯片 - GTX314L规格参数介绍
  8. SpringBoot中的Bean
  9. 2022-2028年中国化学浆行业调查与发展前景预测报告
  10. 电脑不能通过adb 连接手机的解决办法