在子目录中使用 target_sources() 命令时用于单元测试 (qtest) 的项目结构

Project Structure for unit testing (qtest) when using target_sources() command in sub directory

首先,我知道这个论坛里有很多类似的问题。但是,none 确实回答了我的具体情况。 我有以下项目结构:

|---Project_Root
    |---CMakeLists.txt
    |---build
    |---src
    |   |---CMakeLists.txt
    |   |---many .cpp and .h files in multiple subfolders with a different CMakeLists.txt 
    |---tests
    |   |---CMakeLists.txt
    |   |---many .cpp files

在 Project_Root/CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)

set(SRC_DIR src)

project(
        Project
        LANGUAGES CXX
        )

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(${PROJECT_NAME} "")
target_include_directories(${PROJECT_NAME} PRIVATE ${SRC_DIR})
add_subdirectory(${SRC_DIR})

在 src 文件夹和子文件夹 CMakeLists.txt 个文件中:

cmake_minimum_required(VERSION 3.5)

set(SRC_FILES
    Source1.cpp
    )

set(HEADER_FILES
    Source1.hpp
    )
target_sources(${PROJECT_NAME}
        PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FILES}
        ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILES}
        )

现在在测试子文件夹中:

project(Test LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
enable_testing()

add_executable(Test tst_test.cpp)
add_test(NAME Test COMMAND Test)

target_link_libraries(Test PRIVATE Qt5::Test)

在上面CMakeLists.txt我想把主项目作为一个静态库包含进来。例如,我可以在根 CMakeLists.txt 中添加一个新的库目标(比如 Project_Lib),然后再次使用命令:

target_sources(Project_Lib
        PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FILES}
        ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER_FILES}
        )

在所有子文件夹中。 但是有没有更优雅的方式来做到这一点而不必修改子文件夹中的所有CMakeLists.txt?例如,有没有办法从 Project 目标中提取源文件,以便可以重新使用它来制作 Project_Lib 目标?

如您所述,您可以创建一个新的静态库目标 Project_Lib。利用您使用项目名称 参数化 目标名称这一事实 (${PROJECT_NAME}),因此您实际上不必更改所有 CMakeLists.txt 子文件夹中的文件。只需更改项目名称即可。

正如我评论的那样,只需 从静态库中排除 main.cpp 文件,并将其添加到单独的可执行目标。

在Project_Root/CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)

set(SRC_DIR src)

# Change the project name, as now the static library is the primary target.
project(
        Project_Lib
        LANGUAGES CXX
        )

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Create the static library target, whose sources are populated in subdirectories.
add_library(${PROJECT_NAME} STATIC)
target_include_directories(${PROJECT_NAME} PRIVATE ${SRC_DIR})
# The only modification necessary in the subdirectories is to *exclude* the 
# main.cpp file from the target_sources for the static library.
add_subdirectory(${SRC_DIR})

# Add *only* the main.cpp file to the executable target.
add_executable(Project_Exe src/main.cpp)
# Link the static library target to the executable.
target_link_libraries(Project_Exe PRIVATE ${PROJECT_NAME})

在tests/CMakeLists.txt:

...
# Link the static library to your Test executable also.
target_link_libraries(Test PRIVATE Project_Lib Qt5::Test)