Phương pháp hiện đại để đặt cờ biên dịch chung trong CMake là gì?


84

Có nhiều cơ chế được cung cấp bởi CMake để đưa cờ đến trình biên dịch:

Có phương pháp nào được ưa chuộng hơn phương pháp kia trong sử dụng hiện đại không? Nếu vậy tại sao? Ngoài ra, làm thế nào phương pháp này có thể được sử dụng với nhiều hệ thống cấu hình như MSVC?


Câu trả lời:


94

Đối với CMake hiện đại (phiên bản 2.8.12 trở lên), bạn nên sử dụng target_compile_options, sử dụng thuộc tính đích bên trong.

CMAKE_<LANG>_FLAGSlà một biến toàn cục và dễ xảy ra lỗi nhất khi sử dụng. Nó cũng không hỗ trợ các biểu thức trình tạo , điều này có thể rất hữu ích.

add_compile_options dựa trên thuộc tính thư mục, điều này tốt trong một số trường hợp, nhưng thường không phải là cách tự nhiên nhất để chỉ định các tùy chọn.

target_compile_optionshoạt động trên cơ sở mỗi mục tiêu (thông qua việc đặt thuộc tính COMPILE_OPTIONSINTERFACE_COMPILE_OPTIONSmục tiêu), thường dẫn đến mã CMake sạch nhất, vì các tùy chọn biên dịch cho tệp nguồn được xác định theo dự án mà tệp đó thuộc về (chứ không phải là thư mục mà nó được đặt trên đĩa cứng). Điều này có lợi thế bổ sung là nó tự động xử lý các tùy chọn chuyển đến các mục tiêu phụ thuộc nếu được yêu cầu.

Mặc dù chúng dài dòng hơn một chút, các lệnh cho mỗi mục tiêu cho phép kiểm soát chi tiết hợp lý đối với các tùy chọn xây dựng khác nhau và (theo kinh nghiệm cá nhân của tôi) ít gây đau đầu nhất về lâu dài.

Về lý thuyết, bạn cũng có thể đặt các thuộc tính tương ứng trực tiếp bằng cách sử dụng set_target_properties, nhưng target_compile_optionsthường dễ đọc hơn.

Ví dụ: để đặt các tùy chọn biên dịch của một mục tiêu foodựa trên cấu hình bằng cách sử dụng các biểu thức trình tạo, bạn có thể viết:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")

12
Lưu ý rằng hãy target_compile_options thêm các tùy chọn, vì vậy bạn có thể sửa đổi dòng cuối cùng như thế này để làm cho nó dễ đọc hơn)

2
@ComicSansMS Câu trả lời tuyệt vời và hay nhất (và cập nhật nhất) mà tôi có thể tìm thấy trên internet. Cảm ơn!
Ela782

Nếu tôi muốn có cùng một bộ cờ biên dịch nghiêm ngặt trên toàn cầu, thì cách tốt nhất hiện đại nhất để làm điều đó là gì? Chỉ định lặp đi lặp lại các cờ giống nhau cho các mục tiêu khác nhau bằng target_compile_options có vẻ là một ý tưởng tồi
user3667089 23/09/17

1
@ user3667089 Các thuộc tính mục tiêu cụ thể thường được khởi tạo bởi một biến hoặc thuộc tính thư mục. Trang chủ cho tài sản tương ứng cho bạn biết chính xác. Trong trường hợp tùy chọn biên dịch, thuộc tính COMPILE_OPTIONSthư mục thực hiện điều này. Bạn có thể sử dụng add_compile_optionslệnh để thiết lập điều này. Các tùy chọn mà đây là một cách tiếp cận tốt thường rất ít và xa.
ComicSansMS

6
@ComicSansMS Việc sử dụng PUBLICtrong là target_compile_optionsgì?
Ramana Reddy
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.