Tôi muốn nâng cao các giải pháp khác bằng cách cung cấp tệp CMakeLists.txt
thực sự hoạt động cũng trong điều kiện xây dựng các phụ thuộc.
Giải pháp lạm dụng CMake
cmake_minimum_required(VERSION 2.8)
add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)
target_link_libraries(mainexec combinedLib) # Important to place before add_custom_target
set(LIBNAME "combinedLib.lib")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
DEPENDS lib1 lib2
COMMENT "Combining libs..."
)
add_custom_target(combinedLib
DEPENDS ${LIBNAME}
)
Lưu ý rằng giải pháp này hoạt động rất xa với Visual Studio nhưng tôi đoán nó có thể được thực hiện đa nền tảng phù hợp.Tôi có thể tưởng tượng rằng các phiên bản sau có thể làm việc cho các nền tảng Unix-based:
set(LIBNAME "libCombinedLib.a")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND ar -rcT ${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
DEPENDS lib1 lib2
COMMENT "Combining libs..."
)
Lưu ý rằng các giải pháp này bằng cách nào đó lạm dụng CMake vì nó sẽ phàn nàn về một mục tiêu của loại UTILITY (thay vì tĩnh hoặc chia sẻ) nếu bạn đặt target_link_libraries
gọi sau tuyên bố add_custom_target
.
CMake mục tiêu khai tuân thủ giải pháp
Để làm cho nó CMake phù hợp, bạn có thể thay thế 'gọi target_link_libraries' bởi
target_link_libraries(mainexec ${LIBNAME})
add_dependencies(mainexec combinedLib)
Trong trường hợp của tôi nó không phải là hoàn toàn thỏa đáng vì mainexec
có để biết về combinedLib
mặc dù nó dự kiến tất cả các phụ thuộc sẽ được xử lý bằng cuộc gọi target_link_libraries
.
giải pháp thay thế với ít khớp nối
Nhìn một chút nữa về phía mục tiêu nhập khẩu Tôi cuối cùng đã tìm thấy một giải pháp mà giải quyết vấn đề cuối cùng của tôi:
cmake_minimum_required(VERSION 2.8)
add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)
set(LIBNAME "combinedLib.lib")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
DEPENDS lib1 lib2
COMMENT "Combining libs..."
)
add_custom_target(combinedLibGenerator
DEPENDS ${LIBNAME}
)
add_library(combinedLib STATIC IMPORTED)
set_property(TARGET combinedLib PROPERTY IMPORTED_LOCATION ${LIBNAME})
add_dependencies(combinedLib combinedLibGenerator)
target_link_libraries(mainexec combinedLib)
Nếu bạn có ý định để modularize toàn bộ thêm GLOBAL
sau STATIC IMPORTED
để làm cho mục tiêu được nhập trên toàn cầu hiển thị.
di động giải pháp CMake
Với các phiên bản CMake hiện CMake cung cấp hỗ trợ đầy đủ cho phụ thuộc bắc cầu và các thư viện giao diện. Sau đó, một thư viện giao diện có thể "liên kết" với các thư viện khác và thư viện giao diện này có thể bị "liên kết". Tại sao dấu ngoặc kép? Trong khi điều này hoạt động tốt, điều này thực sự không tạo ra một thư viện vật lý, kết hợp mà là tạo ra một loại bí danh cho tập hợp các "thư mục con". Tuy nhiên, đây là giải pháp mà chúng tôi cần cuối cùng, đó là lý do tại sao tôi muốn thêm nó vào đây.
add_library(combinedLib INTERFACE)
target_link_libraries(combinedLib INTERFACE lib1 lib2)
target_link_libraries(mainexec combinedLib)
Vậy đó!
Bạn có phiên bản tĩnh của thư viện cần được liên kết không? Hay bạn chỉ có phiên bản dùng chung? – tpg2114
tôi có phiên bản tĩnh – Rolle
Vì vậy, khi bạn nói nó không bao gồm chúng trong tĩnh của bạn, là nó cố gắng liên kết thư viện tĩnh của bạn với các thư viện được chia sẻ khác? – tpg2114