如何在Ubuntu中更改默认的GCC编译器?

119

我已经在Ubuntu 11.04上安装了gcc-3.3/g++-3.3,该系统已经安装了gcc/g++-4.4。所以在我的系统中,gcc-3.3和4.4都是可用的。我可以按照需要调用两个编译器。如果我只调用gcc命令,则会调用gcc-4.4。要调用gcc-3.3,我必须使用gcc-3.3命令。

如何将默认编译器更改为gcc-3.3?当我执行gcc命令时,它应该调用gcc-3.3而不是gcc-4.4。

此外,如何在make文件中更改变量CXX为gcc-3.3?我希望更改系统中一个通用的全局位置,而不是更改所有make文件。


2
对于CXX标志,您可以调用CXX = gcc-3.3export CXX = gcc-3.3,然后使用make。但是,当您使用update-alternatives全局更改时,它将已经使用gcc-3.3,因此这是不必要的。 - DipSwitch
1
@RoboAlex:我再次更新了我的答案,以考虑你的CXX环境变量请求。但请注意,这仅在您稍后修改update-alternatives时才会生效。 - jopasserat
你只需要更改你的PATH。大多数答案都提到了替代系统,但是Debian和LLVM维护者都同意替代系统应该用于替代,而不是用于版本控制。在我的回答中进一步解释。 - hmijail
8个回答

134

正如@Tommy建议的那样,您应该使用update-alternatives
它为软件家族中的每个软件分配值,从而定义了调用应用程序的顺序。

它用于在系统上维护相同软件的不同版本。 在您的情况下,您将能够使用几个不同版本的gcc,并且其中一个将被优先选择。

要查找gcc的当前优先级,请键入@tripleee评论中指出的命令:

update-alternatives --query gcc

现在请注意gcc-4.4所具有的优先级,因为您需要为gcc-3.3提供更高的优先级。
要设置备选项,您应该像这样操作(假设您的gcc安装位于/usr/bin/gcc-3.3gcc-4.4的优先级低于50)

update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-3.3 50

--编辑--

最后,你还可以使用update-alternatives的交互式界面来轻松切换版本。输入update-alternatives --config gcc,然后选择你想要在已安装的版本中使用的gcc版本。

--编辑2--

现在,为了系统范围内修复CXX环境变量,你需要将@DipSwitch指出的那行代码放入你的.bashrc文件中(这样只会应用于当前用户,我认为更加安全):

echo 'export CXX=/usr/bin/gcc-3.3' >> ~/.bashrc

1
@thang也被称为ccroot@host:/root# update-alternatives --get-selections | grep '/usr/bin/gcc' cc auto /usr/bin/gcc - jopasserat
当我运行“update-alternatives --config gcc”时,什么也没有发生,尽管我有系统的gcc和anaconda的gcc。 - Kelthar
你如何自动化地完成这个过程呢?这需要手动检查 update-alternatives --query gcc 的输出,这在自动化的配置脚本中可能无法正常工作。另外,如何使其跨平台兼容? - ely

77

以下是 jHackTheRipper 回答的完整示例,适用于 TL;DR 读者。 :-) 在这种情况下,我希望在 Ubuntu 系统上运行 g++-4.5,而该系统默认为 4.6 版本。以 root 身份执行以下操作:

apt-get install g++-4.5
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 100
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.5 50
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 100
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.5 50
update-alternatives --install /usr/bin/cpp cpp-bin /usr/bin/cpp-4.6 100
update-alternatives --install /usr/bin/cpp cpp-bin /usr/bin/cpp-4.5 50
update-alternatives --set g++ /usr/bin/g++-4.5
update-alternatives --set gcc /usr/bin/gcc-4.5
update-alternatives --set cpp-bin /usr/bin/cpp-4.5

在这里,4.6仍然是默认值(也称为“自动模式”),但我暂时明确切换到了4.5(手动模式)。要返回到4.6:

update-alternatives --auto g++
update-alternatives --auto gcc
update-alternatives --auto cpp-bin

(请注意使用cpp-bin而不仅仅是cpp。Ubuntu已经有一个具有主链接/lib/cppcpp可替代程序。重命名该链接将删除/lib/cpp链接,可能会破坏脚本。)


8
对于未来的懒人,想将安装的g++-5编译器设置为默认值:sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 100 - geometrian
只剩下一个问题:为什么在安装g++-6软件包时APT不会执行此操作? - rustyx
我已经切换默认编译器为g++-5,但它仍然使用g++-7标准库,现在我遇到了未定义的__builtin错误。 - Youda008

28

这是一个很好的描述,提供了逐步说明如何创建和管理主(master)和从(slave)(gcc和g++)替代方案的步骤。

简而言之:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7
sudo update-alternatives --config gcc

1
这个“40和60”是什么意思?我正在尝试使用gcc-6。 - nyxee
1
@nyxee 40和60表示分配给每个条目的优先级,请查看其他答案以获取更完整的主题。 - jopasserat

15

在所有--slaves中,取值介于4.8到6之间:

update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 \
                    10 \
                    --slave   /usr/bin/cc cc /usr/bin/gcc-4.8 \
                    --slave   /usr/bin/c++ c++ /usr/bin/g++-4.8 \
                    --slave   /usr/bin/g++ g++ /usr/bin/g++-4.8 \
                    --slave   /usr/bin/gcov gcov /usr/bin/gcov-4.8 \
                    --slave   /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-4.8 \
                    --slave   /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-4.8 \
                    --slave   /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-4.8 \
                    --slave   /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-4.8 \
                    --slave   /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-4.8

update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 \
                    15 \
                    --slave   /usr/bin/cc cc /usr/bin/gcc-6 \
                    --slave   /usr/bin/c++ c++ /usr/bin/g++-6 \
                    --slave   /usr/bin/g++ g++ /usr/bin/g++-6 \
                    --slave   /usr/bin/gcov gcov /usr/bin/gcov-6 \
                    --slave   /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-6 \
                    --slave   /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-6 \
                    --slave   /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-6 \
                    --slave   /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-6 \
                    --slave   /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-6

使用update-alternatives --config gcc在它们之间进行切换。


4
删除 ccc++ 相关的代码行后,程序正常运行,这些代码导致了错误:备选项 cc 无法作为 gcc 的从属项,因为它是一个主要的备选项。 - palik
1
这是正确的方法。所有GCC实用程序都应该被配置。 - Jingguo Yao

7

现在,Ubuntu/precise 可以使用 gcc-4.9。

创建一个编译器备选组,使得发行版自带的编译器具有更高的优先级:

root$ VER=4.6 ; PRIO=60
root$ update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VER $PRIO --slave /usr/bin/g++ g++ /usr/bin/g++-$VER
root$ update-alternatives --install /usr/bin/cpp cpp-bin /usr/bin/cpp-$VER $PRIO

root$ VER=4.9 ; PRIO=40
root$ update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VER $PRIO --slave /usr/bin/g++ g++ /usr/bin/g++-$VER
root$ update-alternatives --install /usr/bin/cpp cpp-bin /usr/bin/cpp-$VER $PRIO

注意:使用gcc版本切换命令将自动更改g++的版本。cpp-bin需要单独进行,因为存在“cpp”主替代品。

列出可用的编译器替代品:

root$ update-alternatives --list gcc
root$ update-alternatives --list cpp-bin

为了手动选择gcc、g++和cpp的版本4.9,请执行以下操作:
root$ update-alternatives --config gcc
root$ update-alternatives --config cpp-bin

检查编译器版本:

root$ for i in gcc g++ cpp ; do $i --version ; done

恢复发行版编译器设置(这里是回到v4.6):

root$ update-alternatives --auto gcc
root$ update-alternatives --auto cpp-bin

4
我在尝试安装新的clang编译器时发现了这个问题。事实证明,DebianLLVM维护者们都同意应该使用替代系统来进行备选项,而不是版本控制。
他们提出的解决方案类似于这样:
PATH=/usr/lib/llvm-3.7/bin:$PATH
其中/usr/lib/llvm-3.7/bin是由llvm-3.7软件包创建的目录,其中包含所有工具的非后缀名称。有了这个,llvm-config(版本3.7)将以其普通名称出现在您的PATH中。无需操纵符号链接,也不需要调用安装在/usr/bin中的llvm-config-3.7。
此外,请检查名为llvm-defaults(或gcc-defaults)的软件包,它可能提供其他方法来执行此操作(我没有使用它)。

非常棒的解决方案!我用它来选择自定义构建的“gcc”套件。 - Mad Calm

1

如果您想以更快(但仍非常干净)的方式实现个人目的(例如,如果您想构建一个特定项目,并且对编译器版本有一些强烈要求),只需按照以下步骤操作:

  • 键入echo $PATH并查找具有非常高优先级的个人目录(在我的情况下,我有~/.local/bin);
  • 在此目录中添加符号链接:

例如:

ln -s /usr/bin/gcc-WHATEVER ~/.local/bin/gcc
ln -s /usr/bin/g++-WHATEVER ~/.local/bin/g++

当然,这对于单个用户有效(它不是系统范围的解决方案),但另一方面我不喜欢在我的安装中改变太多东西。

那么你正在创建自己的特别,与系统并行的替代系统。为什么不使用真正的东西呢? - hmijail
@hmijail,正如我所解释的那样,当我想构建一个独立项目而不会弄乱整个安装时,我会使用这种方法。它非常有效,我可以很容易地在之后删除它。 - Thomas Baruchel
1
只需更改您的 PATH,就可以更快、更干净,同时保持您的 GCC 相关工具同步。 - hmijail

0

我只使用了以下几行代码,就成功地编译了 VirtualBoxVMWare WorkStationUbuntu 14.04 上的 kernel 4.8.10。最初,大部分功能都无法正常工作,例如图形和网络。幸运的是,VMWare Workstation 要求使用 gcc 6.2.0。由于 virtualbox 崩溃,我无法启动我的 Genymotion Android 模拟器。如果需要,稍后将发布结果。

VER=4.6 ; PRIO=60
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VER $PRIO --slave /usr/bin/g++ g++ /usr/bin/g++-$VER
VER=6 ; PRIO=50
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VER $PRIO --slave /usr/bin/g++ g++ /usr/bin/g++-$VER
VER=4.8 ; PRIO=40
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-$VER $PRIO --slave /usr/bin/g++ g++ /usr/bin/g++-$VER

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接