首页 文章

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

提问于
浏览
8

我正在开发一个由3个服务器可执行文件和一个共享代码库组成的项目 . 我希望它是跨平台的,所以我使用CMake(因为Xcode很痛苦)来处理构建过程 . 我在设置CMakeLists时遇到问题,以便在构建可执行文件时可以从同一级别的目录中包含库 .

这是目录结构(和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”,这是加密库的头文件 . 这看起来很好 . 对此的任何想法也非常感谢!

1 回答

  • 14

    我的解决方案是使用add_subdirectory和shared_lib目录的相对补丁 . 我不认为这是一个完美的解决方案,它有其警告:

    • 必须将与 Headers 保护非常相似的逻辑添加到库CMakeLists.txt中,以防止多次定义目标 .

    • 每个CMakeList.txt文件必须知道库的相对补丁,如果想要移动库,则必须更新所有CMakeLists .

    我们假设目录结构如下所示:

    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 的变量 . 这种方法有助于解决一些问题 .

    根/ 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 中库的include目录

    根/ 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()
    

相关问题