如何选择默认的gcc和g ++版本?

所以我安装了gcc-4.4和gcc-4.3(对于g ++也一样)。 现在据我所知,Ubuntu中有一个工具,如果你只是告诉它你想要哪个版本,它会为你设置符号链接。 然而,它似乎不适用于最新版本,我觉得令人失望。

root@nexus:~# update-alternatives --config gcc update-alternatives: error: no alternatives for gcc. root@nexus:~# update-alternatives --config cc There is only one alternative in link group cc: /usr/bin/gcc Nothing to configure. root@nexus:~# dpkg -l | grep gcc | awk '{print $2}' gcc gcc-4.3 gcc-4.3-base gcc-4.3-multilib gcc-4.4 gcc-4.4-base gcc-4.4-multilib gcc-4.5-base gcc-multilib lib32gcc1 libgcc1 

有任何想法吗?

首先删除了gcc和g ++的当前更新替代设置:

 sudo update-alternatives --remove-all gcc sudo update-alternatives --remove-all g++ 

安装包

看来gcc-4.3和gcc-4.4都是在安装build-essential之后安装的。 但是,我们可以显式安装以下包:

 sudo apt-get install gcc-4.3 gcc-4.4 g++-4.3 g++-4.4 

安装替代品

默认情况下安装符号链接cc和c ++。 我们将为gcc和g ++安装符号链接,然后分别将cc和c ++链接到gcc和g ++。

 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 10 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30 sudo update-alternatives --set cc /usr/bin/gcc sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30 sudo update-alternatives --set c++ /usr/bin/g++ 

配置替代品

最后一步是配置gcc,g ++的默认命令。 交互式地在4.3和4.4之间切换很容易:

 sudo update-alternatives --config gcc sudo update-alternatives --config g++ 

或者使用脚本切换:

 #!/bin/sh if [ -z "$1" ]; then echo "usage: $0 version" 1>&2 exit 1 fi if [ ! -f "/usr/bin/gcc-$1" ] || [ ! -f "/usr/bin/g++-$1" ]; then echo "no such version gcc/g++ installed" 1>&2 exit 1 fi update-alternatives --set gcc "/usr/bin/gcc-$1" update-alternatives --set g++ "/usr/bin/g++-$1" 

在终端执行:

 gcc -v g++ -v 

好的,这部分很简单。 棘手的部分是当你发出命令GCC时,它实际上是一个sybolic链接,你正在使用的GCC版本。 这意味着我们可以创建从GCC到我们想要的任何GCC版本的符号链接。

  • 你可以看到符号链接:
 ls -la /usr/bin | grep gcc-4.4 ls -la /usr/bin | grep g++-4.4 
  • 所以我们需要做的是删除GCC符号链接和G ++符号链接,然后重新创建它们链接到GCC 4.3和G ++ 4.3:
 rm /usr/bin/gcc rm /usr/bin/g++ ln -s /usr/bin/gcc-4.3 /usr/bin/gcc ln -s /usr/bin/g++-4.3 /usr/bin/g++ 
  • 现在,如果我们再次检查符号链接,我们将看到GCC和G ++现在链接到GCC 4.3和G ++ 4.3:
 ls -la /usr/bin/ | grep gcc ls -la /usr/bin/ | grep g++ 
  • 最后,我们可以再次检查我们的GCC -v并确保我们使用的是正确的版本:
 gcc -v g++ -v 

这真的很可取吗? gcc版本之间存在ABI更改。 使用一个版本(例如整个操作系统)编译某些内容然后使用其他版本编译其他内容可能会导致冲突。

例如,应始终使用用于编译内核的相同版本的gcc编译内核模块。 考虑到这一点,如果您手动更改/usr/bin/gcc与您的Ubuntu版本中使用的版本之间的符号链接,未来DKMS构建的模块可能使用错误的gcc版本。

如果你只是想用不同版本的gcc构建东西,这很容易,即使是makecripts也是如此。 例如,您可以在CC环境变量中传入gcc的版本:

 CC="gcc-4.5" ./configure CC="gcc-4.5" make 

你可能不需要make命令(配置脚本通常将其拉入),但它没有受到伤害。

编辑:

这假定您已经安装了该版本,例如:

 sudo apt install gcc-4.9 g++-4.9 

原版的:

对于那些懒惰的人来说,这是一个单行,只需将最后的数字更改为您想要的版本。 它将对gcc和/或g ++进行更改

 ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[az]+)*[\s]" | xargs bash -c 'for link in ${@:1}; do sudo ln -s -f "/usr/bin/${link}-${0}" "/usr/bin/${link}"; done' 4.9 

在这个例子中,我切换到4.9

没有错误检查以及此示例中没有的内容,因此您可能希望在运行之前检查将运行的内容。 只需在sudo之前添加echo 。 为了完整性,我也提供了检查线:

 ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[az]+)*[\s]" | xargs bash -c 'for link in ${@:1}; do echo sudo ln -s -f "/usr/bin/${link}-${0}" "/usr/bin/${link}"; done' 4.9 

检查的输出应该是这样的:

 sudo ln -s -f /usr/bin/g++-4.9 /usr/bin/g++ sudo ln -s -f /usr/bin/gcc-4.9 /usr/bin/gcc sudo ln -s -f /usr/bin/gcc-ar-4.9 /usr/bin/gcc-ar sudo ln -s -f /usr/bin/gcc-nm-4.9 /usr/bin/gcc-nm sudo ln -s -f /usr/bin/gcc-ranlib-4.9 /usr/bin/gcc-ranlib sudo ln -s -f /usr/bin/x86_64-linux-gnu-g++-4.9 /usr/bin/x86_64-linux-gnu-g++ sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-4.9 /usr/bin/x86_64-linux-gnu-gcc sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ar-4.9 /usr/bin/x86_64-linux-gnu-gcc-ar sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-nm-4.9 /usr/bin/x86_64-linux-gnu-gcc-nm sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ranlib-4.9 /usr/bin/x86_64-linux-gnu-gcc-ranlib 

你可以用以下方法查看版本:

 gcc --version 

半详细解释:

  • ls -la / usr / bin /列出/ usr / bin中的所有文件
  • | 将输出管道(发送)到下一个命令
  • grep -oP匹配每行的搜索正则表达式。 o仅显示结果而不是整个匹配的行。 P告诉grep使用perl-regex。 我不会在这里进入正则表达式,如果你愿意,请阅读它。
  • xargs简单地说,它收集管道传输给它的结果并将所有结果发送到最后。 即对xargs之后的命令
  • 好吧,这是打击。 c标志告诉它使用字符串作为命令。 在这个例子中,它通过跳过第一个(第0个)参数来循环遍历从xargs发送的参数,在这种情况下,循环跳过4.9 。 第0个参数在循环中用于更改链接。
  • ln -s -f s标志创建一个符号链接,如果需要, f强制首先取消链接。

考虑单向升级:

  • sudo apt install gcc-7
  • sudo apt remove gcc-5

在这种情况下,apt会自动处理链接人员。 新的C / C ++版本非常兼容。 你几乎不需要旧的。