デフォルトのgccおよびg ++バージョンの選択方法


206

そこで、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

何か案は?


1
@Oliが説明したように、これは悪い考えです。Debian-develメーリングリスト:「バージョン管理に代替手段を使用すべきではないと考えています。たとえば、gccに代替手段を使用せず、Pythonにも代替手段を使用しません。」lists.debian.org/debian-devel/2014/06/msg00381.html
hmijail

1
では、バージョン管理に何を使用しますか?
-WillC

回答:


271

最初に、gccおよびg ++の現在の更新代替セットアップを消去しました。

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 ++にリンクします。(1020および30オプションは各選択肢の優先順位であることに注意してください。)

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"

4
Thxなので、それらを手動でupdate-alternativesに追加する必要があります。IIRCの以前のUbuntuバージョンでは自動的に追加されていました。
ニルス

1
これは、異なるカーネル用にnvidiaモジュールをコンパイルするときに特に役立ちます。update-alternativesをご説明いただきありがとうございます
earthmeLon

1
ありがとうございました!他の回答を使用して、4.6から4.7に更新しました。私はこの答えを使いたかったのですが、何人かのコマンドの後に10 20 30のような数字を入力する理由がわかりませんでした。説明してもらえますか?
マーティン・ドロズディク

7
マンページによると、数字は結局のところ優先順位です。バージョンの1つがアンインストールされた場合、それらの優先順位を使用して、どのバージョンが新しいデフォルトになるかを判断します。
イブラヒム

1
@Ibrahim:いいえ、彼らはあなたがオートモード選択時に選択しますかを決定
クッキー

41

ターミナルで実行:

gcc -v
g++ -v

さて、その部分はかなり簡単です。扱いにくい部分は、コマンドGCCを発行するとき、実際に使用している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

1
まさに私が探していたものです!「gcc」をインストールしたバージョンにシンボリックリンクする機能を忘れました。ありがとう!
CalebHC

よりシンプルで簡単で安全な方法!
sailfish009

21

これは本当に望ましいですか?gccバージョン間でABIの変更があります。あるバージョン(オペレーティングシステム全体など)で何かをコンパイルしてから、別のバージョンで別のものをコンパイルすると、競合が発生する可能性があります。

たとえば、カーネルモジュールは常にgcc、カーネルのコンパイルに使用したのと同じバージョンでコンパイルする必要があります。それを念頭に置いて、手動/usr/bin/gccでUbuntuのバージョンで使用されているバージョンとシンボリックリンクを手動で変更した場合、将来のDKMSビルドモジュールは間違ったgccバージョンを使用する可能性があります。

の異なるバージョンで物事を構築したいだけならgcc、makescriptを使っても簡単です。たとえばgccCC環境変数にのバージョンを渡すことができます。

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

makeコマンドでは必要ないかもしれませんが(構成スクリプトは通常それを取り込みます)、それは害はありません。


1
あなたのコメントのためのThx。私はCC変数を知っていますが、これは本当に問題ではありませんでした。
ニルス

2
十分に真実ですが、なぜシステムのgcc一部でalternativesはないのか、なぜこれが特に望ましくないのかを説明しました。どちらも気に入らない場合は、手動で変更してください。
オリ

1
前だった?今、彼らはそれを削除しましたか?!異なるバージョンのgccでコンパイル(ユーザ空間)ソフトウェアは、この議論は敷居きます。..完全に[OK]をする必要があり...
ニルス

1
呼び出しごとの環境変数がシステム全体の構成設定よりも望ましい理由を説明できますか? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 一方、sudo update-alternatives gcc gcc-7誤ってABIを切り替えないようにしたはずです。
kfsone

14

編集:

これは、最初にバージョンをインストールしたことを前提としています。例:

sudo apt install gcc-4.9 g++-4.9

元の:

そして、ここに怠zyな人のためのワンライナーがあります、あなたが望むバージョンに最後に数字を変更してください。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

半詳細な説明:

  • 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必要に応じて、最初のリンク解除力を。

2
非常に古い質問ですが、この回答は古い投稿への回答を確認するときに探すべき宝石の1つであるようです...
mook765

ブリリアント!最高の答えは伝承!
ガブリエルステープルズ

-1

一時ディレクトリ内のシンボリックリンクはどうですか:

mkdir x && PATH=$PWD/x:$PATH && ln -s /usr/bin/g++-7 $PWD/x/g++


認めざるを得ない。これは素晴らしい答えだ。
user643722
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.