2012-12-01 31 views
7

C++ - dự án, nói rằng, foo được duy trì bởi cmake. Một người muốn tạo một thư viện libfoo.a (với tất cả các lớp/phương pháp/chức năng được tạo ở toàn bộ cây nguồn) để tạo các chương trình có thể có thể liên kết với thư viện với -lfoo.tạo một thư viện tĩnh từ toàn bộ dự án với cmake

ok, bây giờ hãy xem xét ví dụ về đồ chơi và phần mở đầu sẽ rõ ràng. Thư mục foo (thư mục gốc của dự án) chứa các thư mục ab. Hai CmakeLists.txt được tạo ra:

# a/CMakeLists.txt 
add_library(A <a_sources>) 
# b/CMakeLists.txt 
add_library(B <b_sources>) 

Và một CMakeLists.txt cho thư mục gốc:

add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> 
target_link_libraries(foo A B) 

Đó là một bất ngờ đối với tôi: sau khi xây dựng libfoo.a chỉ chứa các phương pháp từ foo_sourcesa_sources, b_sources Bị loại trừ. Đó là ok trong trường hợp khi thực thi được xây dựng với cùng một dự án: trong khi tạo thực thi cmake "đoán" rằng ab phải được liên kết nếu nó được liên kết với foo. Nhưng trong trường hợp thực thi được tạo ra "bên ngoài" dự án để sử dụng thư viện foo một phải liên kết với -lfoo -la -lb, bây giờ tưởng tượng một dự án với rất nhiều thư mục con - làm thế nào để đối phó với nó? vì vậy câu hỏi là "làm thế nào để tạo ra một thư viện, phương pháp tổng hợp từ toàn bộ dự án với các phương tiện của cmake?"

Googling dẫn tôi đến tương đối gần đây được nhúng (xuất hiện trong 2.8.8) OBJECT library cơ hội. Ví dụ đẹp về việc sử dụng nó được hiển thị here. Bây giờ vấn đề trên có thể được giải quyết với điều đó:

# a/CMakeLists.txt 
add_library(A OBJECT <a_sources>) 
# b/CMakeLists.txt 
add_library(B OBJECT <b_sources>) 
# foo/CMakeLists.txt 
add_subdirectory(a) 
add_subdirectory(b) 
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>) 

vấn đề dường như đã được giải quyết, thật không may, không hoàn toàn.

nếu chuỗi phụ thuộc dài hơn 2, ví dụ: foo tùy thuộc vào A, phụ thuộc vào B, sự cố vẫn còn. Đó là vì,

Thư viện đối tượng chỉ có thể chứa nguồn (và tiêu đề) biên dịch cho tệp đối tượng.

Object thư viện không thể được nhập khẩu, xuất khẩu, cài đặt, hoặc liên kết.

(dấu ngoặc kép được lấy từ cùng một link)

Tôi đã thử một vài sự kết hợp của target_link_library(), add_library(), add_library(... OBJECT ..) cố gắng liên kết AB-foo nhưng không thành công (lỗi trong quá trình cmake quá trình.)

Tôi phải mất một cái gì đó đơn giản, xin vui lòng giúp đỡ, cảm ơn bạn! Tôi không chắc là nó quan trọng: dự án được duy trì ở linux.

Trả lời

3

Tôi nghĩ bạn đang bị rối trong thuật ngữ "phụ thuộc vào".Nếu bạn đang xây dựng một thư viện có tên là foo và có hai phần, AB, không quan trọng là A có phụ thuộc vào B hay không; thư viện nên chứa cả hai. Mã CMake mà bạn đã hiển thị sẽ xây dựng foo đúng cách.

0

Vâng, tôi hỗ trợ câu trả lời @Pete Becker @. Nhưng cũng nên nói rằng các thư viện đó là $<TARGET_OBJECTS:A>$<TARGET_OBJECTS:B> thực sự không phải là một thư viện nào cả, mà đúng hơn là lấy danh sách nội bộ của các mô-đun đối tượng. Không có sự phụ thuộc giữa việc biên dịch các mô-đun đối tượng (trừ các nguồn được tạo tự động) để chúng có thể được thực hiện theo thứ tự bất kỳ và song song.

Tôi đoán cụm từ chính xác hơn cho ý định của bạn đang tập hợp một số TARGET_OBJECTS dưới thư viện đối tượng đơn lẻ. Đó là thực sự xấu mà bạn không thể viết add_library(B OBJECT b.cpp $<TARGET_OBJECTS:A>). Nhưng bạn luôn có thể thực hiện điều này bằng cách tự hỏi:

add_library(A OBJECT a.cpp) 
set(A_OBJECTS $<TARGET_OBJECTS:A>) 

add_library(B OBJECT b.cpp) 
set(B_OBJECTS $<TARGET_OBJECTS:B> ${A_OBJECTS}) 

add_library(foo ${B_OBJECTS}) 

tức là chỉ cần tạo các biến đặc biệt _OBJECTS để sử dụng chúng bất cứ khi nào bạn muốn bao gồm các thư viện đối tượng trong thư viện, thực thi hoặc là một phần của thư viện đối tượng khác với điều đó _OBJECTS hương vị.

Các vấn đề liên quan