CMake:使用相同静态库的多个子项目

Int*_*idd 21 static cmake

我正在使用cmake编译我的一个工作项目,这是交易

-
  client/
    CMakeLists.txt
  server/
    CMakeLists.txt
  libs/
    libstuff/
      CMakeLists.txt
  CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)

所以我希望能够单独编译每个子项目,并从根文件夹构建客户端和服务器.

假设客户端和服务器需要libstuff.

我尝试在客户端和服务器CMakeLists.txt中使用"add_subdirectory"和lib的路径,它在编译服务器或客户端时有效,但是如果您尝试从根目录运行两者:

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.
Run Code Online (Sandbox Code Playgroud)

所以我是一个新的w/cmake,我不知道我应该做什么,我应该使用add_dependencies?

谢谢你的帮助,

sak*_*kra 30

一个简单的解决方案是使用TARGET条件保护add_subdirectory客户端和服务器CMake列表文件中的调用,即:if

if (NOT TARGET plugin)
    add_subdirectory("${CMAKE_SOURCE_DIR}/common/libplugin")
endif() 
Run Code Online (Sandbox Code Playgroud)

这可以防止libplugin子目录多次添加.


And*_*dré 5

我建议在你的根CMakeLists.txt中放三个add_subdirectory调用.首先是libstuff,然后是客户端和服务器....

将Stuff项目设置为独立项目,但将变量添加到cmake缓存中,以便可以由其他项目"导入".然后,在客户端和服务器中,您可以使用普通调用include_directoriestarget_link_libraries来引用Stuff项目.

例如在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 )
Run Code Online (Sandbox Code Playgroud)

然后在客户端(和服务器中的类似)

# 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 )
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过单步执行客户端目录并在那里运行make或msbuild来"编译"客户端目录.或者,您可以在root-cmakelistt中添加一个cmake-flag,用于在Client,Server或两者之间进行过滤...