Sự khác biệt giữa include_directories và target_include_directories trong CMake là gì?


134

Tôi có một cấu trúc thư mục cho mã C ++ của mình như sau:

|
|->include
|->src

Tôi đang viết một tệp CMakeLists.txt cho mã của mình. Tôi muốn hiểu sự khác biệt giữa include_directoriestarget_include_directoriestrong CMake.

Sự khác biệt giữa cách sử dụng của chúng và để thêm đường dẫn tệp bao gồm của tôi mà tôi nên sử dụng là gì?


4
Bạn đã đọc tài liệu cho include_directoriestarget_include_directories? Bạn không hiểu gì về sự khác biệt giữa chúng?
Một số lập trình viên anh chàng

74
Không có sự rõ ràng trong tài liệu. Tôi đã đọc nó và phỏng đoán những gì Angew đã viết trong câu trả lời của anh ấy, nhưng không có mô tả, không có ví dụ và đối với một hệ thống dành cho xây dựng dự án, không có ví dụ dựa trên dự án trong tài liệu CMake. Đã có một tài liệu tốt và đầy đủ về CMake, tôi sẽ không gây gánh nặng cho cộng đồng với những câu hỏi này.
Ujjwal Aryan

Các khái niệm về cmake là tài liệu kém. Đặc biệt là mục tiêu và không có mục tiêu
John Greene

Câu trả lời:


148

include_directories(x/y)ảnh hưởng đến phạm vi thư mục. Tất cả các mục tiêu trong CMakeList này, cũng như các mục tiêu trong tất cả các thư mục con được thêm vào sau điểm gọi của nó, sẽ có đường dẫn x/yđược thêm vào đường dẫn bao gồm của chúng.

target_include_directories(t x/y)có phạm vi mục tiêu, nó bổ sung x/yvào đường dẫn bao gồm cho mục tiêu t.

Bạn muốn cái trước nếu tất cả các mục tiêu của bạn sử dụng các thư mục bao gồm trong câu hỏi. Bạn muốn cái sau nếu đường dẫn dành riêng cho mục tiêu hoặc nếu bạn muốn kiểm soát tốt hơn khả năng hiển thị của đường dẫn. Sau đó xuất phát từ thực tế là target_include_directories()hỗ trợ PRIVATE, PUBLICINTERFACEvòng loại.


35
Tôi nghĩ rằng cái sau thường nên được ưu tiên (miễn là người ta đang sử dụng cmake 3). Nó có thêm lợi ích của việc đưa x/yvào đường dẫn bao gồm của bất kỳ mục tiêu phụ thuộc nào sử dụng ttrong các target_link_librarieslệnh của chúng . Tất nhiên có một nơi dành cho người trước, nhưng tôi tin rằng cái sau nói chung là tốt hơn.
Phil

2
Câu trả lời ban đầu nói rằng chỉ các mục tiêu và thư mục con được thêm vào sau include_directoriessẽ bị ảnh hưởng. Tôi đang chỉnh sửa câu trả lời: tài liệu nêu rõ rằng tất cả các mục tiêu trong CMakeLists hiện tại đều bị ảnh hưởng. Tài liệu này không đề cập mà chỉ có các thư mục con sau khi cuộc gọi bị ảnh hưởng (như đã được nêu chính xác trong câu trả lời ban đầu)
tamas.kenez

@Phil, target_include_directoriesđã được giới thiệu trong CMake 2.8.11 (tháng 5 năm 2013)
tamas.kenez

@ tamas.kenez Cảm ơn bạn đã chú ý đến điều này. Tôi đã hoàn toàn tin rằng đó là một điều "từ bây giờ".
Angew không còn tự hào về SO 13/08/2015

40

Bên cạnh những gì câu trả lời của Angew nói chính xác, một sự khác biệt rất quan trọng khác giữa include_directoriestarget_include_directoriesđó là, khi được sử dụng với PUBLIChoặc INTERFACE, cái sau sẽ tạo ra thuộc INTERFACE_INCLUDE_DIRECTORIEStính của mục tiêu. Thuộc tính này hữu ích khi một mục tiêu khác sử dụng target_link_librariesđể liên kết đến mục tiêu ban đầu, vì mục tiêu liên kết sẽ tự động bao gồm các thư mục được thêm vào. Xem ví dụ .

Tính năng quan trọng này được ẩn khá tốt trong tài liệu: target_include_directories đề cập đến dân cư INTERFACE_INCLUDE_DIRECTORIES, có tài liệu nói:

Khi các phụ thuộc đích được chỉ định bằng cách sử dụng target_link_l Library () , CMake sẽ đọc thuộc tính này từ tất cả các phụ thuộc đích để xác định các thuộc tính xây dựng của người tiêu dùng.


Đây là lần đầu tiên tôi từng đọc một lời giải thích dễ hiểu về các PUBLICthuộc tính vv! Cảm ơn: D
RL-S

2

Như @Angew đã nói, sự khác biệt rất lớn là:

1, include_directories () có thể truy cập được đối với tất cả các tệp trong cây nguồn 2, target_include_directories () chỉ có thể truy cập được cho một mục tiêu cụ thể khi biên dịch.

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.