Xác định macro tiền xử lý thông qua CMake?


Câu trả lời:


382

Trong một thời gian dài, CMake đã có add_definitionslệnh cho mục đích này. Tuy nhiên, gần đây lệnh đã được thay thế bằng một cách tiếp cận chi tiết hơn (các lệnh riêng biệt cho các định nghĩa biên dịch, bao gồm các thư mục và các tùy chọn trình biên dịch).

Một ví dụ sử dụng add_compile_def địnhs mới :

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION})
add_compile_definitions(WITH_OPENCV2)

Hoặc là:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

Điểm hay của việc này là nó phá vỡ sự lừa đảo tồi tệ mà CMake đã áp dụng add_definitions. CMake là một hệ thống tồi tàn như vậy, nhưng cuối cùng họ cũng tìm thấy sự tỉnh táo.

Tìm thêm lời giải thích về những lệnh sẽ sử dụng cho cờ trình biên dịch tại đây: https://cmake.org/cmake/help/latest/command/add_def địnhs.html

Tương tự như vậy, bạn có thể thực hiện điều này theo từng mục tiêu như được giải thích trong câu trả lời của Jim Hunziker.


4
Từ trang được liên kết: "Lưu ý Lệnh này đã được thay thế bằng các lựa chọn thay thế: Sử dụng add_compile_def địnhs () để thêm các định nghĩa tiền xử lý." Có lẽ câu trả lời này cần một chỉnh sửa?
M.Herzkamp

9
Trong cmake 3.10.2, add_compile_definitionsném CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".. Phải sử dụng add_compile_options(-D <your-def>)thay thế.
code_dredd

2
@mannyglover Tôi không nghĩ vậy, nhưng bạn có thể đặt cờ trình biên dịch với -D, một cái gì đó dọc theo dòng cmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(không được kiểm tra)
ypnos

1
Nó thực sự mới ... thực tế nó là trong CMake hiện đại hơn (> 3.11). Một nỗi đau mà thật khó để biết khi nào một lệnh được đưa ra.
Sandburg

1
@Sandburg Bạn có thể mở liên kết đến tài liệu cuối cùng: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionsvà bắt đầu thay đổi số phiên bản cho đến khi trang biến mất. Đó sẽ là phiên bản mà nó chưa tồn tại. Trong bước tiếp theo, bạn có thể vào Whats newphần để tìm lệnh hoặc tính năng mới. Vì vậy, nó không quá khó.
Andry

245

Để làm điều này cho một mục tiêu cụ thể, bạn có thể làm như sau:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

Bạn nên làm điều này nếu bạn có nhiều mục tiêu mà bạn đang xây dựng và bạn không muốn tất cả chúng sử dụng cùng một cờ. Đồng thời xem tài liệu chính thức về target_compile_def địnhs .


1
@JimHunziker target_compile_definitions(my_target PRIVATE FOO=1)khác với set_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)như thế nào?
John Strood

1
@JohnStrood Sự khác biệt là ở cấp độ phạm vi. target_compile_definitionsđặt giá trị cho thư viện / thư viện thực thi WHOLE, trong đó 'set_source_files_properIES` chỉ đặt giá trị cho tệp được chỉ định. Lệnh Latter cho phép các tệp được biên dịch bằng một ngôn ngữ khác; tức là : set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-c. Lưu ý rằng -x objective-cđây là một cờ cụ thể cho GCC / Clang.
Julian Kirsch

20

Giải pháp khác được đề xuất trên trang này là một số phiên bản3.3.2 hữu ích của Cmake < . Đây là giải pháp cho phiên bản tôi đang sử dụng (nghĩa là 3.3.2). Kiểm tra phiên bản Cmake của bạn bằng cách sử dụng $ cmake --versionvà chọn giải pháp phù hợp với nhu cầu của bạn. Các tài liệu cmake có thể được tìm thấy trên trang chính thức.

Với phiên bản CMake 3.3.2, để tạo

#define foo

Tôi cần sử dụng:

add_definitions(-Dfoo)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

và, để có định nghĩa macro tiền xử lý như định nghĩa khác:

#define foo=5

dòng được sửa đổi:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

4
Theo tài liệu , giải pháp này thực sự là phương pháp cũ hơn, cổ xưa hơn. Các câu trả lời khác cung cấp các giải pháp hiện đại hơn.
squareskittles 23/07/19

2
Khi tôi viết câu trả lời, tôi đã thử giải pháp khác nhưng không ai trong số họ làm việc.
Leos313

@squareskittles, có ai biết giải pháp tại sao câu trả lời khác không hoạt động chính xác không? CMake đưa ra lỗi nếu tôi thử chúng
Leos313

1
Nếu bạn đang sử dụng CMake 3.3.2, như bạn đã chỉ ra trong câu trả lời của mình, bạn phải sử dụng add_definitions()hoặc target_compile_definitions(). Lệnh hiện đại hơn add_compile_definitions(), đã không được thêm vào cho đến CMake 3.12. @ Leos313
squareskittles

1
@squareskittles, tôi đang cập nhật câu trả lời, viết lại những gì tôi đã viết một số mounths trước đây. Cảm ơn bạn đã chỉ ra điều này
Leos313
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.