Làm cách nào để yêu cầu CMake liên kết trong thư viện tĩnh trong thư mục nguồn?


96

Tôi có một dự án nhỏ với Makefile mà tôi đang cố gắng chuyển đổi sang CMake, chủ yếu chỉ để có kinh nghiệm với CMake. Đối với mục đích của ví dụ này, dự án chứa một tệp nguồn (C ++, mặc dù tôi không nghĩ rằng ngôn ngữ này có liên quan đặc biệt) và một tệp thư viện tĩnh mà tôi đã sao chép từ nơi khác. Giả sử vì lợi ích của đối số rằng mã nguồn của thư viện không có sẵn; Tôi chỉ có tệp .a và tiêu đề tương ứng.

Makefile thủ công của tôi chứa quy tắc xây dựng này:

main: main.o libbingitup.a
    g++ -o main main.o libbingitup.a

hoạt động tốt. Làm cách nào để yêu cầu CMake tái tạo điều này? Tất nhiên, không phải là makefile chính xác theo nghĩa đen mà là thứ bao gồm lệnh liên kết tương đương. Tôi đã thử những cách hiển nhiên nhưng ngây thơ, như

add_executable(main main.cpp libbingitup.a)

hoặc là

add_executable(main main.cpp)
target_link_libraries(main libbingitup.a)

cũng như nhiều thứ khác nhau có link_directories(.)hoặc add_library(bingitup STATIC IMPORTED)vv nhưng không có gì cho đến nay dẫn đến liên kết thành công. Tôi nên làm gì đây?


Chi tiết phiên bản: CMake 2.8.7 trên Linux (Kubuntu 12.04) với GCC 4.6.3

Câu trả lời:


121

CMake ủng hộ việc chuyển toàn bộ đường dẫn đến các thư viện liên kết, vì vậy giả sử có libbingitup.a ${CMAKE_SOURCE_DIR}, làm như sau sẽ thành công:

add_executable(main main.cpp)
target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)

2
Tuyệt vời, điều đó hoạt động, cảm ơn! Có vẻ như một chút hackish có để đưa vào đường dẫn đầy đủ một cách rõ ràng ở đây, nhưng tôi đoán rằng nhân chỉ cách CMake ...
David Z

4
Tôi đồng ý rằng nó có vẻ như quá mức cần thiết ở đây, nhưng việc chỉ định rõ ràng đường dẫn đầy đủ trả cổ tức nếu bạn cài đặt nhiều phiên bản khác nhau của cùng một lib.
Fraser

1
Tuyệt vời như thường lệ! Trong trường hợp của tôi, đã giải quyết được vấn đề thư viện phụ thuộc vào một thư viện động được xây dựng khác phụ thuộc vào thư viện tĩnh: các thư viện phụ thuộc cũng đang cố gắng liên kết với thư viện tĩnh này.
Antonio

1
Làm thế nào để main biết về các thư mục bao gồm?
ManuelSchneid3r

3
Bạn cần phải sử dụng target_include_directorieshoặc include_directories(trước đây là cách ưu tiên vì nó cụ thể hơn).
Fraser

31

Nếu bạn không muốn bao gồm đường dẫn đầy đủ, bạn có thể làm

add_executable(main main.cpp)
target_link_libraries(main bingitup)

bingitup là cùng một tên mà bạn đặt mục tiêu nếu bạn tạo thư viện tĩnh trong một dự án CMake:

add_library(bingitup STATIC bingitup.cpp)

CMake tự động thêm phần libtrước và .aphần cuối trên Linux và .libcuối trên Windows.

Nếu thư viện là bên ngoài, bạn có thể muốn thêm đường dẫn đến thư viện bằng cách sử dụng

link_directories(/path/to/libraries/)

1
Và nếu có các tệp .a và .so có cùng tên, làm thế nào bạn chỉ định bạn muốn liên kết với .a hoặc .so trong trường hợp này?
George

1
@George: Bạn không thể. Nếu bạn có cả hai loại, hãy bao gồm tên đầy đủ của tệp bạn muốn liên kết.
Cris Luengo

21

Tôi thấy điều này hữu ích ...

http://www.cmake.org/pipermail/cmake/2011-June/045222.html

Từ ví dụ của họ:

ADD_LIBRARY(boost_unit_test_framework STATIC IMPORTED)
SET_TARGET_PROPERTIES(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a)
TARGET_LINK_LIBRARIES(mytarget A boost_unit_test_framework C)

3
Còn INCLUDE_DIRECTORIES thì sao?
kyb

1
Điều này chỉ hoạt động nếu thư viện là một phần của bản dựng cmake, nhưng các thư viện nước ngoài này không hoạt động
eigenfield

câu hỏi cho biết "dự án chứa tệp nguồn (C ++, mặc dù tôi không nghĩ ngôn ngữ này có liên quan đặc biệt) và tệp thư viện tĩnh mà tôi đã sao chép từ nơi khác."
stu
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.