说惯了面向硬件的操作系统,也应该说说操作系统的主要使用对象–用户程序。要深入理解程序的运作过程,则需要了解编译原理、链接、装载和运行库等知识。一般都是IDE封装了这些过程,一个简单的Shift+F5指令封装了“预编译+编译+汇编+链接+装载”全过程,而要想分割独立地控制或挖掘这些子过程,则不得不借助一些工具,如预编译编译程序cl、汇编器as、链接器link、查看工具dumpbin(针对Windows PE文件结构)、binutils工具套件(配合gcc针对ELF文件结构)等。
利用编译器可以深度控制你自己的代码,并且可以比IDE编译更快,当然付出的代价便是你某种程度上需要事必躬亲,而不像使用IDE那么一键速成。
首先如果你想要在你的windows电脑上使用cl编译器,你首先得把cl编译器的环境变量给设置一下,否则你的命令行将会显示没有这样的启动项或命令。
PATH = **YourVS-install-place**\VC\bin
INCLUDE = **YourVS-install-place**\VC\include
LIB = **YourVS-install-place**\VC\lib
如果提示找不到mspdb80.dll,则需要手动从VC\Common7\IDE下拷贝“msobj80.dll\mspdb80.dll\mspdbcore.dll\mspdbsrv.exe”到VC\bin下即可。
/*CL命令格式*/
CL [option...] file... [option | file] ...[lib] [@command-file] [/link link-opt]
cl [选项...] 文件名...[/link链接选项...]
/*
1. option: 参数选项可以使用“/”或“-”修饰给出
具体含义可使用>cl /help option展示
*********. c/c++ 编译器选项 ---优化----*************
/O1 最小化空间,使得产生的可执行代码最小
/O2 最大化速度,使得优化后的可执行代码运行最快
/Od 禁用优化选项(编译起default)
/Og 启用全局优化
/Oi[-] 启用内部函数,用内部函数去代替程序里的函数调用,可以使程序加速,但是程序长度增加
/Os 偏向于代码空间优化
/Ot 偏向于代码速度优化
/Ox 组合了几个优化开关,最大化优化
/Oy 阻止调用堆栈里,创建帧指针(仅x86)
/favor 对于特定架构平台的优化/favor:[blend/ATOM/AMD64/INTEL64]
**************************************************
*********. c/c++ 编译器选项 ---代码生成----*************
1. /arch:<SSE | SSE2 | AUX> CPU架构的最低要求,以下为选项信息
SSE - 启用支持SSE的CPU可用的指令
SSE2(https://baike.baidu.com/item/SSE2/1190211?fr=aladdin) - 启用支持SSE2的CPU可用的指令
AUX - 支持使用Intel(R)高级矢量扩展指令
2. /GA 对windows应用程序进行优化
3. /Gd 采用__cdecl调用惯例
4. /GD 为Windows动态库DLL做优化,此功能在VC6之前并没有
5. /Ge 对所有函数强制堆栈检查
6. /GF 消除程序中的重复的字符串,并启用只读字符串池,将该字符串放入只读的缓冲区中
7. /Gf 消除程序中的重复字符串
8. /Gh 在每个函数的开头调用钩子函数_penter
9. /GH 在每个函数的末尾启用钩子函数_pexit
10. /GL 启用链接时代码生成,打开整个程序优化
11. /Gm[-] 启用最小重新生成rebuild
12. /GR 打开C++ 运行时类型信息RTTI(RunTime Type Information)
13. /Gr 采用__fastcall 调用规定
14. /GS 检查缓冲区安全检查
15. /Gs[num] 控制堆栈检测所用的内存大小
16. /GT 使用TLS(thread Local storage)静态线程本地存储时保证数据分配安全,
//支持用_declspec(thread)分配的数据的fier-safety
17. /Gv 使用__vectorcall调用惯例
18. /Gw 打开整个程序的全局数据优化
19. /GX 打开同步异常处理,与/EHsc开关等价
20. /Gy[-] 分隔链接器函数,打开函数级链接
21. /GZ 启用堆栈检查(/RTCs)
22. /Gz 使用__stdcall调用惯例
23. /clr[:option] 产生运行在the common language runtime上的输出文件,其中option是:
pure--生成只包含IL的输出文件
safe--生成只包含IL的可验证输出文件
oldSyntax--接受VC++ 2002/2003的托管扩展语法
initialAppDomain--启用VC++ 2002的初始AppDomain行为
noAssembly--不产生程序集
24./hotpatch 确保可热修补映射的函数填充,创建一个补丁镜像
25./QIfist 禁止浮点数转换为整数时调用_fotl(),而使用FIST
26./Qimprecise_fwaits 在try块内部移除FWAITs指令,而仅在try边界生成
27./Qsafe_fp_loads 生成安全FP负载
28./EHs 启用C++ EH(没有SEH异常)
29./EHa 启用C++ EH(w/ SEH异常)
30./EHc 外部“C”默认为nothrow
31./RTC1 启用快速检查
32./RTCc 转换为较小的类型检查
33./RTCs 堆栈帧运行时检查
34./RTCu 未初始化的局部用法检查
/*感觉除了几个调用惯例设置和钩子函数的设置外,其他选项基本上用不到*/
***************************************************************
*********. c/c++ 编译器选项 ---输出文件----*************
1./doc[file] 处理注释文档到一个XML文件
2./Fa[file] 创建汇编列表文件,指定用/FA设置的列表文件的存放路径及(或)文件名
3./FA 配置汇编列表文件,设置生成何种列表文件(汇编、汇编与机器码、汇编与源码、汇编与机器码以及源码)
4./Fd[file] 命名.PDB文件
5./Fe<file> 命名可执行文件
6./Fm[file] 创建mapfile映射文件
7./Fo<file> 命名对象.obj文件
8./Fp<file> 指定预编译头文件
9./Fr[file] 命名源浏览器文件
10./Fi[file] 指定预处理输出的文件名
***************************************************************
*********. c/c++ 编译器选项 ---预处理器----*************
1./AI<dir> Specifies a directory to search to resolve file references passed to the #using directive.添加到程序集搜索路径
2./C Preserves comments during preprocessing.不抽出注释
3./D<name>{=|#}<text> 定义宏,与源程序中#define效果相同
4./E 复制预处理到标准输出
5./EP 复制预处理到标准输出,无行号
6./P 写预处理到一个输出文件,文件的后缀名为I
7./FI<file> 预处理指定的include文件
8./Fx 合并注入代码和源代码,将插入的代码合并到文件中
9./I<dir> 指定include文件搜索路径
10./U 删除预定义宏
11./u 和/U相同
12./X 忽略标准include路径,阻止编译器搜索标准的include目录
13./Yc[file] 创建预编译头文件(.pch)
14./Yd 在所有的obj文件里写上完全的调试信息,将调试信息放在每个.obj文件中
15./Yu[file] 在build过程中使用指定的预编译头文件
16./YX 指示编译器若预编译头文件存在,则使用它,若不存在,则创建一个
***************************************************************
*********. c/c++ 编译器选项 --语言相关----*************
/openmp 启用OpenMP 2.0语言扩展,打开#pragma omp在源代码中
/vd 禁止或者打开隐藏vtordisp类的成员(构造函数置换)
/vmb 选择指针的表示方法,使用这个开关,在声明指向某个类的成员的指针之前,必须先定义这个类,Uses best base for pointers to members.
/vmg 选择指针的表示方法,使用这个开关,在声明指向某个类的成员的指针之前,不必先定义这个类,但是要指定这个类是使用何种继承方法,Uses full generality for pointers to members.
/vmm 设置指针的表示方法为多继承
/vms 设置指针的表示方法为单继承
/vmv 设置指针的表示方法为虚拟继承Any class
/Z7 产生和C 7.0兼容的调试信息
/Za 禁用语音扩展(微软编译器对C的扩展Micrsoft Extension to C)
/Zc 指定一个标准行为在/Ze下
/Zd 调试信息只包含外部和全局的符号信息以及行号信息
/Ze 允许语言扩展(Micrsoft Extension to C)
/Zg 产生函数原型,为源文件里面定义的每个函数生成函数原型
/ZI 生成程序库文件(.Pdb),并支持Edit and Continue调试特性,在程序数据库中包括调试信息(仅x86)
/Zi 生成程序库文件(.Pdb),产生完整的调试信息,启用调试信息
/Zl 从.obj文件中删除默认的库名
/Zp[n] 在n字节边界上包装结构,设置结构成员在内存里面的封装格式
/Zs 快速检查语法错误
/ZW 产生一个输出文件能运行在windows运行环境
***************************************************************
*********. c/c++ 编译器选项 ---链接----*************
/F<num> 设置堆栈尺寸
/LD 创建动态链接库
/LDd 创建一个调试动态链接库含有debug信息
/link 将指定的参数选项传递各链接器
/LN 创建.netmodule,创建一个MSIL模型
/MD 编译创建一个多线程 DLL,使用msvcrt.lib
/MDd 编译创建一个调试多线程 DLL,Debug版本,使用msvcrtd.lib
/MT 编译创建一个多线程执行程序,使用libcmt.lib
/MTd 编译场景一个调试多线程执行程序,Debug版本,使用libcmtd.lib
***************************************************************
*********. c/c++ 编译器选项 ---杂项----*************
/? 列出编译选项
@<file> 指定一个响应文件
/analyze 打开代码分析
/bigobj 生成扩展的对象格式
/c 编译但不链接,即只生成.obj文件
/errorReport<option> 打开在vc++终端中提供内部编译错误信息(ICE)
/FC 显示传递给cl.exe的源代码的完整路径到一个文件中
/FS 强制写入一个程序数据库文件(PDB)
/H<n> 限制外部名字的长度,最大外部名称长度
/HELP 列出编译选项
/J 改变默认char类型,从signed char改成unsigned char
/kernel 编译器和链接器将创建一个可以在windows内核中执行的执行程序
/MP[n] 同时建造多源代码文件,最多使用n个进行编译
/nologo 禁止显示启动版权标志,取消显示版权信息
/sdl 打开一些附加的安全功能和警告
/showIncludes 在编译期间显示全部include文件的列表
/TC 将所有文件看做C源程序编译,不管后缀名是否为.c
/Tc 将指定的文件当作C源程序编译,不管后缀名是否为.c
/TP 将所有文件看做C++源程序编译,不管后缀名是否为.cpp
/Tp 将指定文件当作C++源程序编译,不管后缀名是否为.cpp
/V 版本信息
/Y 禁用所有PCH选项
/Wall 打开全部警告,包括默认关闭的警告
/w 关闭全部警告
/wd<n> 禁用警告n
/we<n> 将警告n视为错误
/wo<n> 将警告n发出一次
/w<l><n> 将警告n设置警告等级1-4
/W<n> 设置警告等级(默认n=1)
/WL 打开在用命令行编译C++源代码时使用一行显示错误和警告信息,启用单行诊断
/WX 将警告视为错误
/Wp64 侦测可能的64-bit问题,启用64位端口定位警告
/Yd 在对象文件中放置完整的调试信息
/Yl 当创建一个调试库时植入PCH引用
/Zm<n> 最大内存分配,默认为百分数%
***************************************************************
*/
vc所支持的文件类型
1) DSW:全称是Developer Studio Workspace,最高级别的配置文件,记录了整个工作空间的配置信息,是一个纯文本的文件,在vc创建新项目的时候自动生成
2) DSP:全称是Developer Studio Project,也是一个配置文件,不过记录的是一个项目的所有配置信息,纯文本文件,相当于manifest文件
3) OPT:与DSW、DSP配合使用的配置文件,记录了与机器硬件有关的信息,同一个项目在不同的机器上的opt文件内容是不同的
4) CLW:记录了跟ClassWizard相关的信息,如果丢失了clw文件,那么在Class View面板里就没有类信息
5) PLG:实际上是一个超文本文件,可以用Internet Explorer打开,记录了Build的过程,是一个日志型文件
6) RC:资源描述文件,记录了所有的资源信息,在资源编辑器里作的修改,实际上都是对RC文件的修改
7) RC2:附加的资源描述文件,不能直接资源编辑器修改,只能手工添加,可以用来添加额外的资源
8) RES:经过资源编辑器编译之后的资源文件,以二进制方式存放
9) SBR:编译器生成的浏览信息文件,在代码导航的时候非常有用,她需要在编译时指定/FR或者/Fr开关
10) BSC:BSCMAKE.EXE将所有的SBR文件作为输入,经过处理之后输出一个BSC文件,在代码导航的时候实际用到的是BSC文件
11) ILK:当选定渐增型编译连接时,连接器自动生成ILK文件,记录连接信息
12) PDB:全称是Program DataBase,即程序数据库文件,用来记录调试信息,是一个相当重要的文件,没有该文件则程序无法正常调试
13) LIB:如果项目输出是Dll的话,一般会输出一个跟项目同名的Lib文件,记录输出的函数信息,俗称胶水代码,一般在link时,可以使用同名.lib,用来指向具体实现的.dll文件
14) EXP:同Lib,是跟Dll一起生成的输出文件
15) PCH:全称是PreCompiled Header,就是预先编译好的头文件,在编译时指定/Yu开关时编译器自动生成