当前位置: 首页>>技术教程>>正文


选择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 ++的当前update-alternatives设置:

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

安装软件包

在安装build-essential后,似乎安装了gcc-4.3和gcc-4.4。但是,我们可以明确安装下列软件包:

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时,它实际上是一个你正在使用的GCC版本的sybolic链接。这意味着我们可以创建一个从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-built模块可能会使用错误的gcc版本。

如果你只是想用不同版本的gcc构建东西,那就足够简单了,即使使用原型。例如,您可以传入CC环境变量中的gcc版本:

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

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

第四种办法

编辑:

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

sudo apt install gcc-4.9 g++-4.9

原版的:

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

ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[a-z]+)*[\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\+\+)(-[a-z]+)*[\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

Semi-detailed解释:

  • ls -la /usr /bin /列出/usr /bin中的所有文件

  • |将输出(发送)到下一个命令

  • grep -oP匹配每行的搜索正则表达式。 o只显示结果而不是整个匹配的行。 P告诉grep使用perl-regex。我不会在这里进入正则表达式,如果你愿意的话,请阅读它。

  • xargs简单地说,它会收集传递给它的结果并将它们全部发送到最后。即遵循xargs的命令

  • 好吧,这是bash。 c标志告诉它使用该字符串作为命令。在这个例子中,它通过跳过第一个(0)参数来循环从xargs发送的参数,在这种情况下,循环跳过了4.9。循环中使用第0个参数来更改链接。

  • ln -s -f s标志是一个符号链接,如果需要,f会首先解除链接。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/315.html,未经允许,请勿转载。