cmake 用于使用通用代码的更大项目

rin*_*883 2 module makefile cmake libraries

我刚刚进入 cmake 是因为我开始从事一个更大的项目。我需要添加模块测试。有几个嵌入式设备,每个都有自己的应用程序在上面运行。

大多数这些应用程序共享代码。所以代码被分成了模块。问题是某些模块在大多数其他模块中使用。这些模块是 common、common-net 和 log。

设备的简化项目(应用程序)具有以下结构:

    .
    |-- CMakeLists.txt (for app)
    |-- LICENSE
    |-- app
    |   |-- inc
    |   |   |-- appfile1.hpp
    |   |   `-- appfile2.hpp
    |   `-- src
    |       |-- appfile1.cpp
    |       |-- appfile2.cpp
    |       `-- main.cpp
    |-- comp
    |   |-- comp1
    |   |   |-- CMakeLists.txt (for test)
    |   |   |-- comp
    |   |   |   |-- CMakeLists.txt (for lib)
    |   |   |   |-- intf
    |   |   |   |   |-- comp1file.hpp
    |   |   |   |   `-- comp1file.hpp
    |   |   |   `-- src
    |   |   |       |-- comp1file.cpp
    |   |   |       `-- comp1file.cpp
    |   |   `-- test
    |   |       `-- src
    |   |           `-- comp1testfile.cpp
    |   |-- comp2
    |   |   |-- CMakeLists.txt (for test)
    |   |   |-- comp
    |   |   |   |-- CMakeLists.txt (for lib)
    |   |   |   |-- inc
    |   |   |   |   `-- comp2file1.hpp
    |   |   |   |-- intf
    |   |   |   |   |-- comp2file2.hpp
    |   |   |   |   |-- comp2file3.hpp
    |   |   |   |   |-- comp2file4.hpp
    |   |   |   `-- src
    |   |   |       |-- comp2file1.cpp
    |   |   |       |-- comp2file2.cpp
    |   |   |       `-- comp2file3.cpp
    |   |   `-- test
    |   |       |-- inc
    |   |       |   `-- comp2testfile.hpp
    |   |       `-- src
    |   |           `-- comp2testfile.cpp
    |   |-- common
    |   |   |-- CMakeLists.txt (for test)
    |   |   `-- comp
    |   |       |-- inc
    |   |       |   |-- commonfile1.hpp
    |   |       |   `-- commonfile2.hpp
    |   |       `-- src
    |   |           `-- commonfile1.cpp
    |   |-- common-net
    |   |   |-- CMakeLists.txt (for test)
    |   |   |-- comp
    |   |   |   |-- inc
    |   |   |   |   |-- netfile1.hpp
    |   |   |   |   |-- netfile2.hpp
    |   |   |   |   |-- netfile3.hpp
    |   |   |   |   |-- netfile4.hpp
    |   |   |   |   |-- netfile5.hpp
    |   |   |   `-- src
    |   |   |       |-- netfile1.cpp
    |   |   |       |-- netfile2.cpp
    |   |   |       |-- netfile3.cpp
    |   |   |       |-- netfile4.cpp
    |   |   |       |-- netfile5.cpp
    |   |   `-- test
    |   |       |-- inc
    |   |       |   |-- nettestfile1.hpp
    |   |       `-- src
    |   |           |-- nettestfile1.cpp
    |   |           |-- nettestfile2.cpp
    |   |           |-- nettestfile3.cpp
    |   |-- comp3
    |   |   |-- CMakeLists.txt (for test)
    |   |   |-- comp
    |   |   |   |-- CMakeLists.txt (for lib)
    |   |   |   |-- intf
    |   |   |   |   |-- comp3file1.hpp
    |   |   |   |   `-- comp3file2.hpp
    |   |   |   `-- src
    |   |   |       `-- comp3file1.cpp
    |   |   `-- test
    |   |       `-- src
    |   |           `-- comp3testfile1.cpp
    |   |-- log
    |   |   `-- comp
    |   |       |-- inc
    |   |       |   |-- logfile1.hpp
    |   |       |   |-- logfile2.hpp
    |   |       |-- intf
    |   |       |   |-- logfile3.hpp
    |   |       |   |-- logfile4.hpp
    |   |       `-- src
    |   |           |-- logfile1.cpp
    |   |           |-- logfile2.cpp
    |   |           |-- logfile3.cpp
    |   |           `-- logfile4.cpp
    |   |-- comp4
    |   |   |-- CMakeLists.txt (for test)
    |   |   |-- comp
    |   |   |   |-- CMakeLists.txt (for lib)
    |   |   |   |-- intf
    |   |   |   |   |-- comp4file1.hpp
    |   |   |   |   |-- comp4file2.hpp
    |   |   |   |   |-- comp4file3.hpp
    |   |   |   `-- src
    |   |   |       |-- comp4file1.cpp
    |   |   |       |-- comp4file2.cpp
    |   |   |       `-- comp4file3.cpp
    |   |   `-- test
    |   |       |-- inc
    |   |       |   |-- comp4testfile1.hpp
    |   |       |   `-- comp4testfile2.hpp
    |   |       `-- src
    |   |           |-- comp4testfile1.cpp
    |   |           |-- comp4testfile2.cpp
    |   |           |-- comp4testfile3.cpp
    |   |           |-- comp4testfile4.cpp
    |   |           `-- comp4testfile5.cpp
    |-- gcc-4.8.cmake
    |-- gcc-4.9.cmake
    `-- gcc-default.cmake
Run Code Online (Sandbox Code Playgroud)

我知道它里面有很多“comp”,但是命名不是由我决定的。

每个 comp 有 2 个 CMakefiles:顶层是创建一个单元测试可执行文件来测试模块。comp 中的一个是创建一个库。这样它就可以与应用程序 CMakefile 中的 add_subdirectory 一起使用。

问题是很多模块都依赖于 common、common-net 和 log。目前这些部分不是作为库构建的。如果在多个模块中使用,我猜是因为 add_subdirectory 会出现问题吗?这个干净吗?

这导致: 每个依赖模块都包含 comp CMakefile 中的公共头文件。在顶层(应用 CMakefile),公共源被添加到可执行文件中。但是对于每个模块测试,我还必须将公共源添加到测试可执行文件中。

这对我来说似乎很奇怪,我认为有些不对劲。但我不知道如何干净地解决它?

查看项目树和独立测试每个模块的需要。在顶级添加源的方法是否可以或没有完成?

Mul*_*als 6

因此,如果我理解正确的话,您会遇到两个单独的问题:必须为每个可执行文件添加公共源,以及必须包含每个可执行文件的公共标头。

您真正应该做的是使每个公共代码库成为 CMake 静态库目标。CMake 解决了项目中库和可执行文件之间的依赖关系,这就是您所拥有的。只要在使用该代码的内容之前添加具有公共代码(common、common-net 和 log)的子目录,您就可以执行类似的操作

target_link_libraries(comp2 common common-net log)
Run Code Online (Sandbox Code Playgroud)

在每个 comp 文件夹中,CMake 将处理依赖项和链接。

更重要的是,您可以将包含路径(以及其他内容)附加到目标,它们将自动应用于链接到它的任何内容。

因此,例如,对于日志库,您可以使用

target_include_directories(log PUBLIC inc intf)
Run Code Online (Sandbox Code Playgroud)

然后,链接到日志库的任何内容都会自动将comp/log/comp/inccomp/log/comp/intf文件夹添加到其标头路径中。

最后,如果我理解正确,你是add_subdirectory-ing的comp4/CMakeLists.txt文件,当您需要一个可执行的测试,并使用comp4/comp/CMakeLists.txt文件,当您需要构建库,包括到应用程序。一个更好的方法是让测试也链接到库。

因此,总而言之,您的项目结构应该看起来像这样:

顶级 CMakeLists.txt

add_subdirectory(comp)
add_subdirectory(app)
Run Code Online (Sandbox Code Playgroud)

comp/CMakeLists.txt

add_subdirectory(common)
add_subdirectory(common-net)
add_subdirectory(log)
add_subdirectory(comp1)
<and so on for the other comps>
Run Code Online (Sandbox Code Playgroud)

comp/common-net/CMakeLists.txt

add_subdirectory(comp)
add_executable(test-common-net <source for test>)
target_link_libraries(test-common-net common-net)
Run Code Online (Sandbox Code Playgroud)

comp/common-net/comp/CMakeLists.txt

add_library(common-net STATIC <source for common-net>)
target_include_directories(common-net PUBLIC inc)

# assuming common-net depends on common
target_link_libraries(common-net common)
Run Code Online (Sandbox Code Playgroud)

comp/comp1/CMakeLists.txt

add_subdirectory(comp)
add_executable(test-comp1 <source for test>)
target_link_libraries(test-comp1 comp1)
Run Code Online (Sandbox Code Playgroud)

comp/comp1/comp/CMakeLists.txt

add_library(comp1 STATIC <source for comp1>)
target_include_directories(comp1 PUBLIC inc)

target_link_libraries(comp1 common common-net log)
Run Code Online (Sandbox Code Playgroud)

你现在可能明白了。您只需要创建一个相互依赖的库链。