2011-12-09 3 views
12

Tôi đang sử dụng cmake để biên dịch một trong projets công việc của tôi, đây là thỏa thuậnCMake: nhiều tiểu dự án sử dụng cùng một thư viện tĩnh

- 
    client/ 
    CMakeLists.txt 
    server/ 
    CMakeLists.txt 
    libs/ 
    libstuff/ 
     CMakeLists.txt 
    CMakeLists.txt 

Vì vậy, tôi muốn để có thể biên dịch mỗi tiểu dự án riêng lẻ, và xây dựng cả máy khách và máy chủ từ thư mục gốc.

Giả sử máy khách và máy chủ cần có phần bổ sung.

Tôi đã cố gắng sử dụng "add_subdirectory" với đường dẫn của lib trong cả máy khách và máy chủ CMakeLists.txt, nó hoạt động khi bạn biên dịch máy chủ hoặc máy khách, nhưng nếu bạn cố gắng chạy cả hai từ thư mục gốc:

CMake Error at common/libplugin/CMakeLists.txt:33 (ADD_LIBRARY): 
    add_library cannot create target "plugin" because another target with the 
    same name already exists. The existing target is a static library created 
    in source directory "/home/adrien/git/r-type/common/libplugin". See 
    documentation for policy CMP0002 for more details. 

Vì vậy, tôi là loại w/cmake mới và tôi không chắc mình nên làm gì, tôi có nên sử dụng add_dependencies không?

Nhờ sự giúp đỡ của bạn,

+0

ý của bạn là gì với "biên dịch riêng"? Nếu bạn xây dựng một dự án VS hoặc makefile, bạn có thể chọn dự án nào để biên dịch ... – Philipp

Trả lời

17

Một giải pháp đơn giản là bảo vệ các cuộc gọi add_subdirectory trong cả máy khách và máy chủ Danh sách CMake nộp với một if sử dụng một TARGET có điều kiện, ví dụ:

if (NOT TARGET plugin) 
    add_subdirectory("${CMAKE_SOURCE_DIR}/common/libplugin") 
endif() 

Điều này ngăn cản các tiểu thư mục libplugin từ được bổ sung nhiều hơn một lần.

+1

Hoạt động tuyệt vời, cảm ơn :) – Intrepidd

5

tôi sẽ đề nghị đưa ba cuộc gọi add_subdirectory trong CMakeLists.txt gốc của bạn. libstuff đầu tiên, sau đó máy khách và máy chủ ....

Thiết lập dự án Stuff như thể nó độc lập, nhưng thêm biến vào bộ nhớ cache cmake để nó có thể được "nhập" bởi các dự án khác. Sau đó, trong máy khách và máy chủ, bạn có thể tham khảo dự án Stuff ... bằng cách sử dụng cuộc gọi thông thường include_directoriestarget_link_libraries.

Ví dụ: trong libstuff ...

# libstuff CMakeLists 
project(Stuff) 
# ... whatever you need here: collect source files, ... 
add_library(LibStuff ${Stuff_Sources}) 
# Then, define a very useful variables which gets exported to the cmakecache and can be 
# used by other cmakelists 
set(STUFF_INCLUDE_DIRS ${Stuff_SOURCE_DIR} CACHE STRING "Include-dir for Stuff." FORCE) 

Và sau đó trong khách hàng (và tương tự trong Server)

# client CMakeLists 
project(Client) 
# refer to Stuff-includes here... 
include_directories(${STUFF_INCLUDE_DIRS}) 

add_executable(Client client.h client.cpp main.cpp) # 
target_link_libraries(Client LibStuff) 

Sau đó, bạn có thể "biên dịch" chỉ thư mục Client, bởi bước vào dir Client và chạy thực hiện hoặc msbuild ở đó. Ngoài ra, bạn có thể thêm cờ cmake vào thư mục gốc-cmakelistt được sử dụng để lọc giữa Máy khách, Máy chủ hoặc cả hai ...

+0

với giải pháp này có thể biên dịch cả máy chủ và máy khách trong một hàng nhưng tôi không thể biên dịch một máy khách độc lập hoặc máy chủ độc lập ... – Intrepidd

+0

Thật vậy, nhưng bạn có thể bước vào thư mục Client (hoặc Server) và biên dịch từ đó. –