CMake 项目结构:如何正确地将库合并在一起并将它们包含在多个可执行文件中

CMake Project Structure: How do I properly merge libraries together and include them in multiple executables

我正在构建一个 C 项目,目前我对如何在库中正确 link 有点迷茫。

总结一下:我将有 3 个项目,这些项目将有多个可执行文件。这些项目将使用来自具有多个目录(子库)的库的代码。我在包含目录中包含项目的所有包含项。我还将为 src 和 lib 提供一个测试目录。

如何 link 在单独目录中的库中?

有没有办法将所有这些库合并到一个主库中,这样我只需要 link 一个库?

结构如下所示:

Project:
   |-- bin   
   |-- build   
   |-- src     
   |   |-- Project 1   
   |   |      |-- Project1a.c
   |   |      |-- Project1b.c
   |   |      |-- cmakelists.txt
   |   |-- Project 2
   |   |      |--Project2.c
   |   |-- Project 3
   |   |      |--Project3.c
   |   |-- cmakelists.txt
   |
   |-- lib 
   |    |--Crypto_Lib
   |    |      |-- Crypto.c
   |    |      |-- cmakelists.txt
   |    |--Communications_Lib
   |    |      |-- Communications.c
   |    |      |-- cmakelists.txt
   |    |--Error_Lib
   |    |      |-- Error.c
   |    |      |-- cmakelists.txt
   |    |--cmakelists.txt
   |
   |-- include
   |    |--src
   |    |   |-- Project 1
   |    |   |     |-- Project1a.h
   |    |   |     |-- Project1b.h
   |    |   |-- Project 2
   |    |   |     |-- Project2.h
   |    |   |-- Project 3
   |    |         |-- Project3.h    
   |    |--lib
   |    |  |--Hash 
   |    |  |    |-- Crypto.h
   |    |  |--Communications
   |    |  |    |-- Communications.h
   |    |  |--Error
   |    |  |    |-- Error.h
   |
   |-- test
   |    |--src (etc...)
   |    |--lib (etc...)
   |    |--cmakelists.txt
   |
   |--cmakelists.txt

CMAKES 我目前有:

~/CMakeLists.txt

    add_subdirectory(lib)
    add_subdirectory(src)
    add_subdirectory(test)

~/lib/CMakeLists.txt

    #To access the header file
    include_directories(${CMAKE_SOURCE_DIR}/includes/lib)   

    add_subdirectory(communications)
    add_subdirectory(crypto)
    add_subdirectory(error)

~/src/CMakeLists.txt

    #To access the header file
    include_directories(${CMAKE_SOURCE_DIR}/includes/src)   

    add_subdirectory(project_one)
    add_subdirectory(project_two)
    add_subdirectory(project_three)

~/lib/communications/CMakeLists.txt

    add_library(Comm_Lib STATIC communications.c)

~/lib/crypto/CMakeLists.txt

    add_library(Crypto _Lib STATIC crypto.c)

~/lib/error/CMakeLists.txt

    add_library(Error_Lib STATIC error.c)

~/src/project_one/CMakeLists.txt

    add_executable(Project_1A Project_1a.c)
    add_executable(Project_1B Project_1B.c)

    #target_link_library(Project_1A Full_Library) Would like to be able to join all libraries together

~/src/project_two/CMakeLists.txt

    add_executable(Project_Three Project_two.c)

~/src/project_one/CMakeLists.txt

    add_executable(Project_Three Project_three.c)

~/test/CMakeLists.txt

    add_subdirectory(lib_test)
    add_subdirectory(src_test)  

    **Haven’t gotten any deeper in the test CMakeLists.txt

我知道我还没有用过 link_libraries,我只是想找出解决这个问题的最佳方法。

感谢您的帮助!

您几乎明白了:您可以 link 您的可执行文件包含在其他目录中定义的库。没问题。

add_executable(Project_1A Project_1a.c)
add_executable(Project_1B Project_1B.c)

target_link_library(Project_1A PUBLIC Full_Library)

但是,我建议您 link 仅针对您直接使用的库部分:

add_executable(Project_1A Project_1a.c)
add_executable(Project_1B Project_1B.c)

# Project_1A only use crypto directly in it's code
target_link_library(Project_1A PUBLIC Crypto_Lib) 

# Project_1B use comm and error directly in it's code
target_link_library(Project_1B PUBLIC Comm_Lib Error_Lib) 

然后不使用 include_directories 函数,而是使用 target_include_directories。有一个选项可以将包含目录添加为使用要求。该要求将传播到使用此要求的其他图书馆:

target_include_directories(Comm_Lib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

通过上面那行,任何 link 到 Comm_Lib 的人都将拥有通信库目录作为包含路径。

如果真的和三个库聚合在一起,Full_Library可以这样定义:

add_library(Full_Library INTERFACE)

target_link_libraries(Full_Library INTERFACE Comm_Lib Crypto_Lib Error_Lib)
target_include_directories(Full_Library INTERFACE common/include/dir)