赞
踩
0.1. 最近在学习“现代C++”的内容,在编程的过程中难免会使用到一些C++的新特性,比如C++17中的内联变量:inline variable
、std::byte
等;然而在编译程序的过程中,发现Ubuntu16.04.6自带的编译器g++会失败,这主要是因为16.04自带的gcc, g++编译器的版本是5.4.0,编译器发布的时间为20160609,那自然肯定编译不了C++17中的东西了。
0.2. 为了能够使用新特性,我们需要升级编译器的版本,而有些古老的程序又需要旧版本来编译,所以这篇博文的重点就来了,也就是:如何优雅地切换gcc, g++编译器的版本,高版本可以当做整个Ubuntu系统默认的编译器,或者高版本为自己编译某些程序时特地指定。
我这里系统的情况:
Linux版本: Ubuntu16.04.6;
使用的C++新特性:C++17;
默认编译器:gcc, g++ (version: 5.4.0)
需要安装的编译器:gcc, g++ (version: 7.4.0)
编译工具: CMake (version: 3.5.1)
用到的IDE(一般指:编辑器+编译器):CLion 2018.1
"现代c++"我浅显的理解就是:C++从2011年(每3年一次,2011的新特性最多,目前使用的也最多,也最为人熟知)开始逐步增加的新特性,比如:
C++11 C++14 C++17 C++20
等在原先C++标准上延伸出来的新特性)
注:为了能够使用C++17的特性,需要gcc-7以上的版本
1.1. 查看编译器版本,可以发现自带的编译器版本为5.4.0;
(因为我将g++版本改了, 所以是7.4, 你们如果没有安装新的gcc, 两者应该都是5.4.0)
1.2. 非常简单的示例demo如下:
// main.cpp
#include <iostream>
#include <cstddef> // for std::byte
int main()
{
std::byte b1{0x3F};
puts("Hello World!");
return 1;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(c++17_test)
set(CMAKE_CXX_FLAGS "-std=c++17")
add_executable(c++17_test main.cpp)
1.3. 使用CMake工具进行编译如下:
1.3. 我们可以看到CMake会输出与编译器的一些信息:
– The C compiler identification is GNU 5.4.0
– The CXX compiler identification is GNU 7.4.0
– Check for working C compiler: /usr/bin/cc
– Check for working C compiler: /usr/bin/cc – works
– Check for working CXX compiler: /usr/bin/c++
– Check for working CXX compiler: /usr/bin/c++ – works
主要是使用GNU来找到合适的编译器,比如gcc, g++;
1.3.1. 这里我们主要来分析一下: CXX compiler: /usr/bin/c++
这里我们想,编译器使用的不是g++吗?为什么这里会是c++?
这里应该也是采取了动态库链接那样类似的机制,c++其实也是一个软链接。
1.3.2. 下面是链接情况:
/usr/bin/c++
-> /etc/alternatives/c++
;
/etc/alternatives/c++
->/usr/bin/g++
;
/usr/bin/g++
->g++-5
(这一步才真正地指到了对应版本g++ -5的可执行程序上,前面两个相当于是个bridge
)
2.1. 如果按照默认的编译器去编译的话,会出现下面的error:
main.cpp:6:5: error: ‘byte’ is not a member of ‘std’ std::byte b1{0x3F};
此版本的g++不支持C++17新特性,所以出现了此类问题,下面就需要将编译器升级到g++ -7以前的版本;
2.2. 命令如下:
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test
$ sudo apt-get update
$ sudo apt-get install gcc-7
$ sudo apt-get install g++-7
g++-7 gcc-7的软链接
/usr/bin/gcc-7
-> /usr/bin/x86_64-linux-gnu-gcc-7
/usr/bin/g++-7
-> /usr/bin/x86_64-linux-gnu-g++-7
g++ --version
的版本依然是默认的5.4.0;这是因为并没有将前面几步讲的bridge
进行软链接,所以现在系统的编译器依然是5.4.0;2.2.1. 如果不进行软链接就不可以使用了吗?那当然不是,就拿CLion这个IDE来说吧,它支持使用者选择具体的编译器,这样我们直接就可以将IDE中的编译器直接指定为g++ -7了,然后在IDE中编译程序了。(File->Settings->Build, Execution, Deployment->Toolchains->C++ Compiler)
2.2.2. Clion中修改为新版本编译器如下(其实只需要修改g++编译器就行):
程序可以正常输出“Hello World”:
2.3. 安装好gcc-7, g++ -7以后,我们可以通过下面的指令将系统的编译器设置为对应的高版本(100对应的是优先级,当存在多个版本的gcc时,如果触发了gcc的自动模式(另外还有手动模式),系统就会根据这个优先级进行自动选择版本):
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 100
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 100
指令会输出信息:
update-alternatives: 使用 /usr/bin/gcc-7 来在自动模式中提供 /usr/bin/gcc (gcc)
update-alternatives: 使用 /usr/bin/g++ -7 来在自动模式中提供 /usr/bin/g++ (g++)
注:可以通过
$ update-alternatives --help
命令明白各个参数的意义。
2.3.1. 这个时候如果去查看版本号,就会发现是新版本7.4.0
:
这个时候各个编译器的链接情况如下(又多添加了alternatives里面的g++ gcc的软链接(相当于一个bridge),最终会链接到新版本的g++ gcc):
/usr/bin/c++
-> /etc/alternatives/c++
;
/etc/alternatives/c++
->/usr/bin/g++
;
/usr/bin/g++
-> /etc/alternatives/g++
;
/etc/alternatives/g++
-> /usr/bin/g++-7
;
/usr/bin/g++-7
-> /usr/bin/x86_64-linux-gnu-g++-7
;
2.4. 编译程序
目前g++版本已经是7.4了,支持C++17新特性了,所以现在可以在1.3节的基础上,进行编译运行:
现在g++, gcc版本已经是新版了,但是如果我们某些程序还是需要依赖低版本的gcc, g++版本编译怎么办?这种情况下就需要我们降级!
3.1. 以下使用g++来进行举例说明,gcc类似的操作;在2.3.1节中通过--config
子命令时会输出信息:
链接组 g++ (提供 /usr/bin/g++)中只有一个候选项:/usr/bin/g++ -7 无需配置。
3.2. 下来我们要做的就是再次install一个软链接(关于低版本的g++ -5):
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 120
由于经常使用旧版本,所以这里将优先级设高为“120”,可以发现此时会触发自动模式
,g++会选择优先级高的g+±5作为编译器:
3.2.1. 如果install的时候,指定旧版本的g++优先级低,它就不会自动切换,因为它会选优先级高的编译器;
3.3. 此种情况下,如果我们想手动指定某个版本的g++,就需要下面的命令来进行切换:
$ sudo update-alternatives --config g++
所以我们可以通过该命令实现对g++版本的切换;(手动输入需要的序号即可)
注意:对于gcc其他的软链接
gcc-ar, gcc-nm
等并不会因为install这些建立软链接,因为install的时候压根没有涉及相关的文件;由于其他使用的并不是很多(一般使用编译器),所以没有考虑这些版本的问题。
3.4. 如果想删除某一个版本的g++,可以使用下面的命令:
例如不再需要g++ -7,则可以使用(且会自动切换为g+±5):
$ sudo update-alternatives --remove g++ /usr/bin/g++-7
3.5. 如果两个g++都删除了,对应的软链接也就失效了,再次install就可以再建立软链接。
4.1. 首先描述了为了编译C++17程序,需要安装g++ -7版本以上的g++;
4.2. 然后进行安装gcc -7, g++ -7;
4.2.1. 对于支持自选编译器的IDE,直接进行指定就更加方便了,不需要其他复杂的操作,只需要安装,指定
即可。
4.3. 然后讲解了如何切换版本,以及编译器的调用过程(各种软链接);
4.4. 虽然升级个g++易如反掌,但是中间的一些处理操作还是值得我们学习。
6.1. 软连接相当于Windows里面的快捷方式;而硬链接创建以后,可以保持对源文件的同步修改,源文件变,硬连接文件变;硬连接变,源文件变。(可以好好利用硬连接这个特性
)
6.2. 硬连接的inode号和源文件的inode号一样,也就是一个i节点号可以对应多个文件名;
在多用户的操作系统里,你写一个脚本,程序等,没有完成,保存后等下次有时间继续写,但是其他用户有可能将你未写完的东西当成垃圾清理掉,这时,你对你的程序,脚本等做一个硬链接,利用硬链接的同步更新,就可以防止别人误删你的源文件了。
i节点是文件和目录的唯一标识,每个文件和目录必有i节点,不然操作系统就无法识别该文件或系统。(也就解释了为什么硬连接和源文件会同步更新);;;;而Git在一方面做得更好
[1]. 软连接和硬链接的区别
[2]. 也可以通过C++官方使用的在线编译器来编译现代C++, 可以指定gcc版本, 指定C++标准, 是一个不错的工具.
[3]. GCC与gcc,g++区别
[4]. Linux的gcc和g++的区别
[5]. Linux——gcc & g++的使用和区别
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。