2011-12-09 16 views
12

estoy usando cmake para compilar una de mis projets de trabajo, aquí es el tratoCRealice: múltiples sub-proyectos que utilizan la misma biblioteca estática

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

así que quiero ser capaz de compilar cada subproyecto individual, y construir tanto el cliente como el servidor de la carpeta raíz.

Digamos que el cliente y el servidor necesitan libstuff.

Traté de usar "add_subdirectory" con la ruta de la lib en el cliente y el servidor CMakeLists.txt, funciona cuando se compila el servidor o el cliente, pero si intenta ejecutar ambos desde el directorio raíz:

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. 

Así que soy un poco nuevo y no estoy seguro de qué debería hacer, ¿debería usar add_dependencies?

Gracias por su ayuda,

+0

¿Qué quieres decir con "compilar por separado"? Si construye un proyecto VS o un archivo MAKE, puede seleccionar qué proyecto compilar ... – Philipp

Respuesta

17

Una solución simple es proteger las llamadas add_subdirectory tanto en el cliente como en el servidor CMake list archivo con una if usando un TARGET condicional, es decir:

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

Esto evita que el sub-directorio libplugin de ser añadido más de una vez.

+1

Funciona muy bien, gracias :) – Intrepidd

5

yo sugeriría poner tres llamadas add_subdirectory en su CMakeLists.txt raíz. primero libstuff, luego cliente y servidor ...

Configure el proyecto Stuff como si fuera independiente, pero agregue variables al cmake cache de modo que otros proyectos lo puedan "importar". Luego, en el cliente y el servidor, puede consultar el proyecto Stuff ... usando la llamada ordinaria include_directories y target_link_libraries.

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

Y luego en cliente (y de manera similar en el servidor)

# 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) 

A continuación, puede "compilar" sólo el directorio del cliente, por entrar en el directorio del cliente y la ejecución de make o msbuild allí. Alternativamente, puede agregar un marcador de marca a la raíz-cmakelistt que se utiliza para filtrar entre Cliente, Servidor o ambos ...

+0

y con esta solución, puede compilar el servidor y los clientes seguidos, pero no puedo compilar un cliente independiente o un servidor independiente ... – Intrepidd

+0

De hecho, pero podría ingresar al directorio de Cliente (o Servidor) y compilar desde allí. –

Cuestiones relacionadas