Cách chỉ định đường dẫn GCC mới cho CMake


122

Hệ điều hành của tôi là centos có đường dẫn gcc mặc định /usr/bin/gcc. Nhưng nó cũ rồi, mình cần phiên bản gcc mới. Vì vậy, tôi cài đặt một phiên bản mới trong một đường dẫn mới /usr/local/bin/gcc.

Nhưng khi tôi chạy cmakethì nó vẫn sử dụng đường dẫn gcc phiên bản cũ ( /usr/bin/gcc). Làm cách nào để chỉ định gcc cho đường dẫn mới ( /usr/local/bin/gcc).

Tôi đã cố gắng ghi đè /usr/bin/gccbằng /usr/local/bin/gcc, nhưng nó không hoạt động.


2
Tôi nghĩ rằng đó là một thực tiễn tốt để cài đặt phiên bản gcc thay thế vào /opthơn là /usr/local. Tốt hơn /opt/gcc-x.y.z. Bằng cách này, nếu bạn cần một phiên bản mới hơn, bạn sẽ không gặp bất kỳ khó khăn nào khi gỡ cài đặt phiên bản trước đó.
user666412

Câu trả lời:


220

Không ghi đè CMAKE_C_COMPILER, nhưng xuất CC(và CXX) trước khi gọi cmake:

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make

Việc xuất chỉ cần được thực hiện một lần, lần đầu tiên bạn định cấu hình dự án, sau đó các giá trị đó sẽ được đọc từ bộ đệm CMake.


CẬP NHẬT : giải thích dài hơn về lý do tại sao không ghi đè CMAKE_C(XX)_COMPILERsau bình luận của Jake

Tôi khuyên bạn không nên ghi đè CMAKE_C(XX)_COMPILER giá trị vì hai lý do chính: vì nó sẽ không hoạt động tốt với bộ nhớ cache của CMake và vì nó phá vỡ kiểm tra trình biên dịch và phát hiện công cụ.

Khi sử dụng setlệnh, bạn có ba tùy chọn:

  • không có bộ nhớ cache, để tạo một biến bình thường
  • với bộ nhớ cache, để tạo một biến được lưu trong bộ nhớ cache
  • buộc bộ nhớ cache, để luôn buộc giá trị bộ nhớ cache khi định cấu hình

Hãy xem điều gì xảy ra cho ba cuộc gọi có thể có set:

Không có bộ nhớ cache

set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)

Khi thực hiện việc này, bạn tạo một biến "bình thường" CMAKE_C(XX)_COMPILERđể ẩn biến bộ nhớ cache cùng tên. Điều đó có nghĩa là trình biên dịch của bạn hiện đã được mã hóa cứng trong tập lệnh xây dựng của bạn và bạn không thể cung cấp cho nó một giá trị tùy chỉnh. Đây sẽ là một vấn đề nếu bạn có nhiều môi trường xây dựng với các trình biên dịch khác nhau. Bạn chỉ có thể cập nhật tập lệnh của mình mỗi khi bạn muốn sử dụng một trình biên dịch khác, nhưng điều đó sẽ loại bỏ giá trị của việc sử dụng CMake ngay từ đầu.

Được rồi, hãy cập nhật bộ nhớ cache ...

Với bộ nhớ cache

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "")
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "")

Phiên bản này sẽ chỉ "không hoạt động". Các CMAKE_C(XX)_COMPILERbiến là đã có trong bộ nhớ cache, vì vậy nó sẽ không được cập nhật, trừ khi bạn buộc nó.

Ah ... chúng ta hãy sử dụng vũ lực, sau đó ...

Buộc bộ nhớ cache

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "" FORCE)
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "" FORCE)

Điều này gần giống với phiên bản biến "bình thường", sự khác biệt duy nhất là giá trị của bạn sẽ được đặt trong bộ nhớ cache, vì vậy người dùng có thể nhìn thấy nó. Nhưng mọi thay đổi sẽ bị ghi đè bởi setlệnh.

Phá vỡ kiểm tra trình biên dịch và công cụ

Đầu quá trình cấu hình, CMake thực hiện kiểm tra trình biên dịch: Nó có hoạt động không? Nó có thể tạo ra các tệp thực thi không? vv Nó cũng sử dụng trình biên dịch để phát hiện các công cụ liên quan, như arranlib. Khi bạn ghi đè giá trị trình biên dịch trong một tập lệnh, thì đã "quá muộn", tất cả các kiểm tra và phát hiện đã được thực hiện.

Ví dụ: trên máy của tôi với gcc làm trình biên dịch mặc định, khi sử dụng setlệnh to /usr/bin/clang, arđược đặt thành /usr/bin/gcc-ar-7. Khi sử dụng xuất trước khi chạy CMake, nó được đặt thành /usr/lib/llvm-3.8/bin/llvm-ar.


Tương đương với những người lười biếng, nếu trình biên dịch thích hợp được đặt trong $ PATH:> export CC = which gcc > export CXX =which g++
gerardw

11
Tương đương với những người lười biếng, nếu trình biên dịch thích hợp được đặt trong $ PATH của bạn: export CC=`which gcc` export CXX=`which g++`
gerardw

Nếu CC / CXX khác với đường dẫn, tôi nhận đượcIncorrect 'gcc' version 'compiler.version=5.3' is not the one detected by CMake: 'GNU=4.8'
Lilith River

1
Làm cách nào để thực hiện việc này nếu tôi đang sử dụng Windows?
mr5

5
Trên thực tế, thiết lập CMAKE_C_COMPILERhoạt động tốt miễn là bạn làm điều đó bằng cách sử dụng dòng lệnh: $ cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ /path/to/source.
Erwan Legrand

25

Câu hỏi này khá cũ nhưng vẫn xuất hiện trên Google Tìm kiếm. Câu hỏi được chấp nhận không còn phù hợp với tôi nữa và dường như đã cũ. Thông tin mới nhất về cmake được viết trong Câu hỏi thường gặp về cmake .

Có nhiều cách khác nhau để thay đổi đường dẫn của trình biên dịch của bạn. Một cách sẽ là

Đặt CMAKE_FOO_COMPILER(các) biến thích hợp thành tên trình biên dịch hợp lệ hoặc đường dẫn đầy đủ trên dòng lệnh bằng cách sử dụng cmake -D. Ví dụ:

cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source

thay vì gcc-4.2bạn có thể viết path/to/your/compilernhư thế này

 cmake -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++ .

2
Tôi đã làm như vậy trong khi xây dựng một dự án cũ trên trình biên dịch cũ (GCC 5.3) trong khi trình biên dịch mới hơn (GCC 7.3) được lấy nguồn trong môi trường. Nó được xây dựng tốt và làm việc trên máy tính của tôi, nhưng khi tôi chuyển thực thi đến một máy khác nhau tôi nhận ra chương trình được liên kết với libstdc ++ như vậy từ các nguồn 7.3 thay vì yêu cầu 5.3 ....
Adam Badura


3

Xuất phải cụ thể về phiên bản GCC / G ++ sẽ sử dụng, vì nếu người dùng có nhiều phiên bản trình biên dịch, nó sẽ không biên dịch thành công.

 export CC=path_of_gcc/gcc-version
 export CXX=path_of_g++/g++-version
 cmake  path_of_project_contain_CMakeList.txt
 make 

Trong trường hợp dự án sử dụng C ++ 11, điều này có thể được xử lý bằng cách sử dụng -std=C++-11cờ trong CMakeList.txt


2

Một giải pháp thay thế là định cấu hình dự án của bạn thông qua cmake-gui, bắt đầu từ một thư mục xây dựng sạch. Trong số các tùy chọn bạn có sẵn lúc đầu, có khả năng chọn đường dẫn chính xác đến trình biên dịch


2

Điều này không chỉ hoạt động với cmakemà còn với ./configuremake:

./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++

Điều này dẫn đến:

checking for gcc... /usr/local/bin/gcc
checking whether the C compiler works... yes

0

Thay đổi CMAKE_<LANG>_COMPILERđường dẫn mà không kích hoạt cấu hình lại

Tôi muốn biên dịch bằng một trình biên dịch thay thế, nhưng cũng chuyển các tùy chọn -D trên dòng lệnh mà sẽ bị xóa bằng cách thiết lập một trình biên dịch khác. Điều này xảy ra vì nó kích hoạt cấu hình lại. Mẹo là vô hiệu hóa tính năng phát hiện trình biên dịch NONEvới FORCE, sau đó đặt đường dẫn bằng enable_language.

project( sample_project NONE )

set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" FORCE )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" FORCE )

enable_language( C CXX )

Sử dụng tệp Chuỗi công cụ

Sự lựa chọn hợp lý hơn là tạo một tệp chuỗi công cụ.

set( CMAKE_SYSTEM_NAME Darwin )

set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" )

Sau đó, bạn gọi Cmake với một cờ bổ sung

cmake -D CMAKE_TOOLCHAIN_FILE=/path/to/toolchain_file.cmake ...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.