简体   繁体   中英

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

First of all, I know there are very similar questions in this forum. However, none really answer my specific case. I have the following project structure:

|---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

In the 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})

In the src folder and subfolder CMakeLists.txt files:

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}
        )

Now in the tests subfolder:

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)

In the above CMakeLists.txt I want to include the main project as a static library. I can, for example, add a new library target (say Project_Lib ) in the root CMakeLists.txt and use once again the command:

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

in all the subfolders. But is there a more elegant way of doing it without having to modify all the CMakeLists.txt in the subfolders ? For example, is there way to extract the source files from the Project target, so that it can be reused to make the Project_Lib target?

As you described, you can make a new static library target Project_Lib . Take advantage of the fact that you parameterized the target name by using the project name ( ${PROJECT_NAME} ), so you actually don't have to change all of the CMakeLists.txt files in the subfolders. Just change the project name.

As I commented, simply exclude the main.cpp file from the static library, and add it to a separate executable target instead.

In 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})

In tests/CMakeLists.txt:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM