基本概念(1)——编译器
c++的编译器常见的有g++、clang++、msvc
- 编译器会自带stl标准库和标准c库,编译器都会有默认自带的搜索路径,c++标准库的头文件和lib、dll等就在编译器的默认搜索路径中
gcc系列
gcc是最经典的编译器,windows中安装gcc可以通过:
1、安装qt,qt自带mingw版本的gcc
2、mingw,手动安装mingw
3、msys64
4、cgwin
等等方式
我的电脑上安装了qt和msys64,msys64目录下的g++搜索路径如下
整理一下
macos bigsur安装gcc可以通过homebrew
可以看到有很多版本,比如安装9.x
如果是Ubuntu,则可以通过apt命令安装gcc
默认安装最新版本,可以通过sudo apt install gcc-7
这种方式指定版本。
安装之后可以通过软连接方式连接到gcc、g++
windows上的gcc可以参考 这里 https://www.cnblogs.com/feipeng8848/p/15227688.html
clang
https://releases.llvm.org/download.html
找到官方编译的二进制包:
下载安装,32位和64位只能安装一个,安装过程中可以选中自动添加到环境变量
安装完之后编译器和调试器就都有了
搜索路径
stl等c++自带的库就在这些目录里
msvc
安装vs之后可以得到的工具有:编译器cl、链接器link.exe、nmake
本机编译器与目标程序
windows系统兼容x86和x64程序,所以编译器(本身就是个软件)可以是x86也可以是x64,于是微软提供了两个版本,分别在Hostx64个Hostx86文件夹中
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin
Hostx64是本机的x64编译器
Hostx86是本机x86编译器
进入Hostx64,里面有4种目标平台
调用Hostx64\arm目录下的cl.exe就是调用本机x64编译器交叉编译生成target是arm的软件
本机x86 和x64编译器
target arm、arm64、x86、x64
这就存在交叉编译的几种组合选择,微软提供了几个脚本方便使用
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build
查看vcvarsall.bat可以看到
amd64和x64实际一样
target(目标机器x64)host(本机环境x86)
命令行使用编译工具
不想在vs中使用cl等工具可以在命令行直接调用cl.exe但是有些初始化参数要添加,为了方便实用微软也提供了脚本,安装完vs会有
其实也都是去调用脚本给给定一些参数最终去调用某个目录下的cl.exe、link.exe工具
参考msdn https://docs.microsoft.com/zh-cn/cpp/build/building-on-the-command-line?view=msvc-160
各种版本
同样是vs2019的vc编译器,又可以安装很多版本(版本号不同)
如果安装vs的时候还安装了vs2015的编译器,那么还可以用vs2015的编译器
MT(d)与MD(d)
带d的是debug版本,不带d是release版本
各编译器之间的兼容性
gcc(exe版本)、clang、msvc这些编译器之间的兼容性并不好,msvc编译得到的dll或者lib使用gcc调用是会不兼容的。
这也是为什么qt的dll为什么会提供好几个版本了,如下图
windows开发使用msvc编译器会更好,因为可以使用的其他第三方组件更多,毕竟他们多数都是msvc编译得到的。
为编译器引入第三方库
ide
以vs为例,使用vs创建的工程,会自动添加一些引用路径,比如vs创建的一个工程,在项目的属性页面:
“包含路径”也就是include的路径,该工程如下
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\atlmfc\include
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\VS\include
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\winrt
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt
C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\Include\um
“库目录”是寻找lib的目录
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\lib\x86
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\atlmfc\lib\x86
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\VS\lib\x86
C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x86
C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86
C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x86
gcc
头文件
gcc 在编译时寻找所需要的头文件 :
※搜寻会从-I开始(gcc 参数,指定头文件搜索位置)
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
※再找内定目录
/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
但是如果装gcc的时候,是有给定的prefix的话,那么就是
/usr/include
prefix/include
prefix/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include
库文件dll
编译的时候:
※gcc会去找-L
※再找gcc的环境变量LIBRARY_PATH
※再找内定目录 /lib:/usr/lib: /usr/local/lib:这是当初compile gcc时写在程序内的