繁体   English   中英

CMake:使用静态库在一个项目中构建多个可执行文件

[英]CMake: Build Multiple Executables in one Project with Static Library

我正在一个由3个服务器可执行文件和一个共享代码库组成的项目中。 我希望它是跨平台的,所以我正在使用CMake(因为无论如何Xcode都很痛苦)来处理构建过程。 我在设置CMakeList时遇到麻烦,因此在构建可执行文件时,可以从同一级别的目录中包含库。

这是目录结构(和CMake文件):

tethealla2.0/
    CMakeLists.txt
    libtethealla/
        CMakeLists.txt
        encryption/
        utils/
    patch_server/
        CMakeLists.txt
    login_server/
        CMakeLists.txt
    ship_server/
        CMakeLists.txt

我的顶级CMake(tethealla2.0 / CMakeLists.txt,仅包括应编译的子项目):

project(tethealla CXX)
cmake_minimum_required(VERSION 2.6)

add_subdirectory(libtethealla)
add_subdirectory(patch_server)

tethealla2.0 / libtethealla / CMakeLists.txt,它生成一个静态库:

project(Libtethealla C)
cmake_minimum_required(VERSION 2.6)

include_directories(encryption)

set(ENC_DR encryption/)

set(ENCRYPTION_SOURCES 
  ${ENC_DR}/psobb-crypt.c
  ${ENC_DR}/psogc-crypt.c
  ${ENC_DR}/psobb-crypt.c
  ${ENC_DR}/encryption.c
  )

add_library(tethealla STATIC ${ENCRYPTION_SOURCES})

到目前为止,tethealla2.0 / patch_server / CMakeLists.txt:

project(patch_server CXX)
cmake_minimum_required(VERSION 2.6)

add_executable(server main.cc)
target_link_libraries(server tethealla)

因此,如果从顶层构建它,则更有意义,因为tethealla2.0 / CMakeLists.txt将继承每个子目录的目标,而patch_server中的子目录将有权访问tethealla库。 但是,我想要的是能够从这些子目录中构建生成Xcode项目,以便我可以分别处理/重新编译它们。 为此,我需要能够进入libtethealla / build目录(CMake输出到该目录)以从patch_server访问libtethealla.a库。 这可能吗?

还有一点需要注意的是,即使是从顶层目录构建,我在patch_server中的源也不能包含“ encryption.h”(加密库的头文件)。 似乎一切正常。 任何想法,也将不胜感激!

我的解决方案是将add_subdirectory与相对补丁一起使用到shared_lib目录。 我认为这不是一个完美的解决方案,但有以下警告:

  • 必须将与标头保护程序非常相似的逻辑添加到库CMakeLists.txt中,以防止多次定义目标。
  • 每个CMakeList.txt文件必须知道库的相对路径,如果要移动库,则必须更新所有CMakeList。

假设目录结构如下所示:

root/
    CMakeLists.txt
    shared_lib/
        CMakeLists.txt
        inc/
            foo.h
        src/
            foo.c
    exec1/
       CMakeLists.txt
       main.c
    exec2/
       CMakeLists.txt
       main.c

根目录/CMakeList.txt

cmake_minimum_required(VERSION 2.6)

add_subdirectory(shared_lib)

add_subdirectory(exec1)
add_subdirectory(exec2)

我已经决定shared_lib / CMakeLists.txt将导出一个名为SHARED_DIR_INCLUDE_DIR的变量。 这种方法有助于使事物脱钩。

root / exec1 / CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

add_subdirectory(./../shared_lib shared_lib)

include_directories(${SHARED_LIB_INCLUDE_DIR})

set(SRCS main.c)
add_executable(exec1 ${SRCS})
target_link_libraries(exec1 shared_lib)

第四行的if()解决了多次添加CMakeLists文件时目标的多重定义的问题。 第二和第三行导出SHARED_LIB_INCLUDE_DIR库的包含目录

root / shared_lib / CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

set(SHARED_LIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc)

set(SHARED_LIB_INCLUDE_DIR ${SHARED_LIB_INCLUDE_DIR} PARENT_SCOPE)

if(TARGET shared_lib)

message("shared_lib is already defined")

else()

include_directories(${SHARED_LIB_INCLUDE_DIR})

set(LIB_SRCS ./src/foo.c)

add_library(shared_lib STATIC ${LIB_SRCS})

endif()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM