2011-12-09 15 views
12

używam cmake skompilować jeden z moich projets pracy, tutaj jest sprawaCWprowadä: wiele podprojekty stosując taką samą statyczną bibliotekę

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

więc chcę, aby móc skompilować każdy podprojekt indywidualnie i budować zarówno klient, jak i serwer z folderu głównego.

Załóżmy, że klient i serwer potrzebują libstuff.

Próbowałem użyć "add_subdirectory" ze ścieżką biblioteki zarówno dla klienta, jak i dla serwera CMakeLists.txt, działa przy kompilacji serwera lub klienta, ale jeśli spróbujesz uruchomić oba z katalogu głównego:

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. 

Więc jestem trochę nowy w/cmake i nie jestem pewien, co powinienem zrobić, powinienem użyć add_dependencies?

Dzięki za pomoc,

+0

co masz na myśli mówiąc "kompiluj oddzielnie"? Jeśli tworzysz projekt VS lub plik Makefile, możesz wybrać, który projekt skompilować ... – Philipp

Odpowiedz

17

Prostym rozwiązaniem jest ochrona wywołań add_subdirectory zarówno na liście klientów, jak i na serwerze CMake plik z if użyciem TARGET warunkowy, tzn:

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

zapobiega to podkatalog libplugin od dodawanych więcej niż jeden raz.

+1

Działa świetnie, dzięki :) – Intrepidd

5

Proponuję wprowadzenie trzech add_subdirectory połączeń w swojej CMakeLists.txt korzeniowego. najpierw libstuff, potem klient i serwer ...

Skonfiguruj projekt Rzeczy tak, jakby był samodzielny, ale dodaj zmienne do pamięci podręcznej cmake tak, aby można je było "importować" przez inne projekty. Następnie, na kliencie i serwerze, możesz odwołać się do projektu Rzeczy ... używając zwykłego połączenia include_directories i target_link_libraries.

E.g. w 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) 

A potem w Client (i podobnie w 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) 

Można potem "skompilować" jedynego katalogu Client, by wchodząc do katalogu Client i działa uczynić lub msbuild tam. Alternatywnie można dodać flagę cmake do root-cmakelistt, która służy do filtrowania między klientem, serwerem lub oboma jednostkami ...

+0

również z tym rozwiązaniem można skompilować zarówno serwer, jak i klientów z rzędu, ale nie mogę skompilować samodzielnego klienta lub autonomicznego serwera ... – Intrepidd

+0

Rzeczywiście, ale możesz wejść do katalogu klienta (lub serwera) i skompilować z niego. –

Powiązane problemy