Câu hỏi Cách chọn phiên bản gcc và g ++ mặc định?


Vì vậy, tôi đã cài đặt gcc-4.4 và gcc-4.3 (tương tự cho g ++). Bây giờ theo như tôi nhớ có một công cụ trong Ubuntu mà thiết lập các liên kết cho bạn nếu bạn chỉ cần nói cho nó phiên bản mà bạn muốn. Tuy nhiên nó không có vẻ làm việc trong phiên bản mới nhất, mà tôi thấy thất vọng.

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

Bất kỳ ý tưởng?


171
2018-02-15 15:52


gốc


Như @Oli đã giải thích, đây là một ý tưởng tồi. Danh sách thư Debian-devel: "Tôi không nghĩ rằng các lựa chọn thay thế nên được sử dụng cho phiên bản. Ví dụ, chúng tôi không sử dụng lựa chọn thay thế cho gcc, không cho Python." lists.debian.org/debian-devel/2014/06/msg00381.html - hmijail


Các câu trả lời:


Trước tiên, hãy xóa thiết lập thay thế cập nhật hiện tại cho gcc và g ++:

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

Cài đặt gói

Có vẻ như cả gcc-4.3 và gcc-4.4 đều được cài đặt sau khi cài đặt build-essential. Tuy nhiên, chúng tôi có thể cài đặt rõ ràng các gói sau:

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

Cài đặt lựa chọn thay thế

Các liên kết tượng trưng cc và c ++ được cài đặt theo mặc định. Chúng tôi sẽ cài đặt các liên kết biểu tượng cho gcc và g ++, sau đó liên kết cc và c ++ với gcc và g ++ tương ứng.

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++

Định cấu hình lựa chọn thay thế

Bước cuối cùng là cấu hình các lệnh mặc định cho gcc, g ++. Thật dễ dàng để chuyển đổi giữa 4,3 và 4,4 tương tác:

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

Hoặc chuyển đổi bằng cách sử dụng tập lệnh:

#!/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"

229
2018-02-15 19:05



Thx, vì vậy bạn phải thêm chúng theo cách thủ công để cập nhật lựa chọn thay thế .. IIRC phiên bản Ubuntu trước đó đã làm điều đó tự động. - Nils
Điều này đặc biệt hữu ích đối với tôi khi biên dịch các mô-đun nvidia cho các hạt nhân khác nhau. Cảm ơn bạn rất nhiều vì đã giải thích các lựa chọn thay thế cập nhật - earthmeLon
Cảm ơn bạn! Tôi đã sử dụng câu trả lời khác của bạn để cập nhật từ 4.6 lên 4.7. Tôi muốn sử dụng câu trả lời này, nhưng tôi không chắc tại sao bạn đặt các con số như 10 20 30 sau một vài lệnh của bạn. Bạn có thể giải thích? - Martin Drozdik
Các con số là ưu tiên khi nó quay ra, theo manpage. Tôi tưởng tượng trong trường hợp một trong các phiên bản được gỡ bỏ cài đặt nó sẽ sử dụng những ưu tiên để xác định cái nào sẽ trở thành mặc định mới. - Ibrahim
@ Ibrahim: Không, họ xác định những gì được chọn khi bạn chọn chế độ tự động - Cookie


thực hiện trong terminal:

gcc -v
g++ -v

Được rồi, vậy phần đó khá đơn giản. Phần khó khăn là khi bạn phát hành lệnh GCC nó thực sự là một liên kết sybolic mà bao giờ phiên bản của GCC bạn đang sử dụng. Điều này có nghĩa là chúng ta có thể tạo ra một liên kết tượng trưng từ GCC đến bất kỳ phiên bản nào của GCC mà chúng ta muốn.

  • Bạn có thể thấy liên kết tượng trưng:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Vì vậy, những gì chúng ta cần làm là loại bỏ liên kết GCC và liên kết tượng trưng G ++ và sau đó tạo lại chúng liên kết với GCC 4.3 và 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++
  • Bây giờ nếu chúng ta kiểm tra lại các liên kết tượng trưng, ​​chúng ta sẽ thấy GCC & G ++ hiện được liên kết với GCC 4.3 và G ++ 4.3:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Cuối cùng, chúng ta có thể kiểm tra GCC -v của chúng ta một lần nữa và chắc chắn rằng chúng ta đang sử dụng đúng phiên bản:
gcc -v
g++ -v

30
2018-02-15 16:49





Điều này thực sự mong muốn? Có những thay đổi ABI giữa gcc phiên bản. Biên dịch một cái gì đó với một phiên bản (ví dụ như toàn bộ hệ điều hành) và sau đó biên dịch một cái gì đó khác với phiên bản khác, có thể gây xung đột.

Ví dụ, mô-đun hạt nhân phải luôn luôn được biên dịch với cùng một phiên bản gcc được sử dụng để biên dịch hạt nhân. Với ý nghĩ đó, nếu bạn thay đổi liên kết tượng trưng theo cách thủ công giữa /usr/bin/gcc và phiên bản được sử dụng trong phiên bản Ubuntu của bạn, các mô-đun được xây dựng DKMS trong tương lai có thể sử dụng sai gcc phiên bản.

Nếu bạn chỉ muốn xây dựng mọi thứ với một phiên bản khác của gcc, thật dễ dàng, ngay cả với bản ghi. Ví dụ: bạn có thể chuyển vào phiên bản gcc bên trong CC biến môi trường:

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

Bạn có thể không cần nó trên lệnh make (cấu hình script thường kéo nó vào) nhưng nó không bị tổn thương.


20
2018-02-15 16:22



Thx cho bình luận của bạn. Tôi biết về biến CC, nhưng đây không thực sự là câu hỏi. - Nils
Đúng nhưng tôi đã giải thích tại sao gcc không phải là một phần của alternatives hệ thống và lý do tại sao điều này không phải là đặc biệt mong muốn. Nếu không ai trong số đó sẽ thay đổi ý định của bạn, chỉ cần làm điều đó theo cách thủ công. - Oli♦
Đó là trước kia? Bây giờ họ chỉ cần loại bỏ nó ?! Biên dịch (userspace) phần mềm với các phiên bản gcc khác nhau nên được hoàn toàn ok .. cuộc thảo luận này là nhận được sill .. - Nils
Bạn có thể giải thích tại sao các biến môi trường trong mỗi yêu cầu lại thích hợp hơn với một thiết lập cấu hình trên toàn hệ thống? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Trong khi sudo update-alternatives gcc gcc-7 chắc chắn rằng bạn không vô tình chuyển ABI. - kfsone


Chỉnh sửa:

Điều này giả định rằng trước tiên bạn đã cài đặt phiên bản, ví dụ:

sudo apt install gcc-4.9 g++-4.9

Nguyên:

Và đây là một lớp lót dành cho những người lười biếng, chỉ thay đổi thay đổi số ở cuối phiên bản bạn muốn. Nó sẽ thực hiện thay đổi cho gcc và / hoặc 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

Trong ví dụ này tôi chuyển sang 4.9

Không có kiểm tra lỗi và những gì không có trong ví dụ này, vì vậy bạn có thể muốn kiểm tra những gì sẽ được chạy trước khi bạn chạy nó. Chỉ cần thêm tiếng vangtrước sudo. Để hoàn thành, tôi cũng cung cấp dòng kiểm tra:

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

Đầu ra từ kiểm tra phải giống như sau:

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

Bạn có thể kiểm tra phiên bản sau với:

gcc --version

Giải thích chi tiết bán:

  • ls -la / usr / bin / liệt kê tất cả các tệp trong / usr / bin
  • | đường ống (gửi) đầu ra cho lệnh tiếp theo
  • grep -oP khớp với regex tìm kiếm trên mỗi dòng. o chỉ hiển thị kết quả chứ không phải toàn bộ dòng phù hợp. P yêu cầu grep sử dụng perl-regex. Tôi sẽ không đi vào regex ở đây, đọc nó nếu bạn muốn.
  • xargs đơn giản chỉ cần đặt, nó tập hợp các kết quả được đường ống đến nó và gửi tất cả chúng đến cùng. tức là lệnh sau xargs
  • bash tốt, nó là bash. Các c để cho nó sử dụng chuỗi như một lệnh. Trong ví dụ này, nó lặp lại các đối số được gửi từ xargs  bằng cách bỏ qua đối số đầu tiên (0), trong trường hợp này, bỏ qua vòng lặp 4.9. Đối số 0 được sử dụng trong vòng lặp để thay đổi liên kết.
  • ln -s -f Các S cờ tạo liên kết tượng trưng, f buộc hủy liên kết trước nếu cần.

10
2017-10-15 20:52



Câu hỏi rất cũ, nhưng câu trả lời này có vẻ là một trong những đá quý mà chúng ta nên tìm kiếm khi xem xét câu trả lời cho các bài viết cũ ... - mook765
Rực rỡ! Câu trả lời hay nhất! - Gabriel Staples


Cân nhắc nâng cấp một chiều:

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

apt sẽ xử lý các nhân viên liên kết tự động trong trường hợp này. Phiên bản C / C ++ mới khá tương thích. Bạn hầu như không bao giờ cần một cái cũ.


-1
2017-10-29 20:02