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

标签 c++ cmake

我正在从事一个项目,该项目包含 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”,即加密库的头文件。这似乎 build 得很好。对此的任何想法也非常感谢!

最佳答案

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

  • 必须将与 header 保护非常相似的逻辑添加到库 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 的变量。这种方法有助于稍微解耦。

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 文件时 target 的多重定义问题。第二行和第三行在 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()

关于c++ - CMake:使用静态库在一个项目中构建多个可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23684789/

相关文章:

c++ - 如何在标题中设置 QTextStream?

C++:为什么定义类对象时可以直接调用 protected 构造函数?

c++ - 循环内切换的性能

cmake - 在 custom_target 中执行 git describe

c++ - 如何在 Windows 上更新已安装库的位置?

c++ - 如何让 cmake 的 PKG_CHECK_MODULES 在 Windows 中找到我的 cairo 库

c++ - 我可以在 CMakeLists 中使用在工具链文件中定义的 CMAKE_SYSTEM_PROCESSOR 吗?

c++ - OpenMP 并行化时出现段错误

CMake 错误 : file INSTALL destination is not a directory

c++ - Opencv矩阵范围L值: Is this a bug?