CMake: несколько подпроектов, использующих одну и ту же статическую библиотеку - PullRequest
17 голосов
/ 09 декабря 2011

Я использую cmake для компиляции одного из моих рабочих проектов, вот сделка

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

Так что я хочу иметь возможность компилировать каждый подпроект индивидуально и собирать клиента и сервер из корневой папки.

Допустим, клиенту и серверу нужен libstuff.

Я попытался использовать «add_subdirectory» с путем к lib в клиенте и на сервере CMakeLists.txt, он работает при компиляции сервера или клиента, но при попытке запустить оба из корневого каталога:

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.

Значит, я новичок в w / cmake, и я не уверен, что мне делать, если я буду использовать add_dependencies?

Спасибо за вашу помощь,

Ответы [ 2 ]

26 голосов
/ 09 декабря 2011

Простое решение заключается в защите вызовов add_subdirectory как в клиентском, так и в серверном файле списка CMake с помощью if с использованием условного выражения TARGET , т.е.* Это предотвращает добавление подкаталога libplugin более одного раза.

5 голосов
/ 09 декабря 2011

Я бы предложил поместить три вызова add_subdirectory в ваш корневой CMakeLists.txt. Сначала libstuff, затем клиент и сервер ....

Настройте проект Stuff так, как если бы он был автономным, но добавьте переменные в кэш cmake, чтобы его можно было «импортировать» другими проектами. Затем в клиенте и на сервере вы можете обратиться к проекту Stuff ... используя обычный вызов include_directories и target_link_libraries .

например. в библиотеке ...

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

А затем в Клиенте (и аналогично в Сервере)

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

Затем вы можете «скомпилировать» только каталог Client, войдя в каталог Client и запустив там make или msbuild. В качестве альтернативы, вы можете добавить cmake-flag в root-cmakelistt, который используется для фильтрации между клиентом, сервером или обоими ...

...