I use CMake to create a DLL
Library. This is my Project Structure:
|---CMakeLists.txt
|
├───include
│ └───FileInput
│ export.hpp (Autogenerated by CMAKE, containing the Export Macros)
│ my_lib.h
├───src
│ my_lib.cpp
│ StringHelper.cpp
│ StringHelper.h
└───tests
CMakeLists.txt
my_libTest.cpp
StringHelperTest.cpp
TestRunner.cpp
And this is my Base CMakeLists.txt
:
cmake_minimum_required(VERSION 3.14)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "Do not build in-source. Please remove CMakeCache.txt and the CMakeFiles/ directory. Then build out-of-source.")
endif()
set(LIBRARY_NAME "FileInput")
project("${LIBRARY_NAME}" VERSION 1.0.0 LANGUAGES CXX)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
message(STATUS "Created target ${LIBRARY_NAME} for export ${PROJECT_NAME}.")
set(${LIBRARY_NAME}_SRC
src/my_lib.cpp
src/StringHelper.cpp
)
set(${LIBRARY_NAME}_PRIVATE_HEADER
src/StringHelper.h
)
set(${LIBRARY_NAME}_HDR
include/${LIBRARY_NAME}/export.hpp
include/${LIBRARY_NAME}/my_lib.h
)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(BUILD_SHARED_LIBS "Build shared (dynamic) libraries." ON)
option(ENABLE_TESTING "Enable a Unit Testing build." ON)
add_library(${LIBRARY_NAME} ${${LIBRARY_NAME}_SRC} ${${LIBRARY_NAME}_HDR} ${${LIBRARY_NAME}_PRIVATE_HEADER})
add_library("ExampleProject::FileInput" ALIAS ${LIBRARY_NAME})
set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${${PROJECT_NAME}_VERSION}
PUBLIC_HEADER "${${LIBRARY_NAME}_HDR}")
if(MSVC)
set_target_properties(${LIBRARY_NAME} PROPERTIES DEBUG_POSTFIX "d")
endif()
target_include_directories(${LIBRARY_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>")
if(NOT BUILD_SHARED_LIBS)
string (TOUPPER ${LIBRARY_NAME} LIBRARY_NAME_UPPER)
set_target_properties(${LIBRARY_NAME} PROPERTIES COMPILE_FLAGS -D${LIBRARY_NAME_UPPER}_STATIC)
endif()
include(GenerateExportHeader)
string (TOUPPER ${LIBRARY_NAME} LIBRARY_NAME_UPPER)
generate_export_header(${LIBRARY_NAME}
EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/${LIBRARY_NAME}/export.hpp
EXPORT_MACRO_NAME ${LIBRARY_NAME_UPPER}_EXPORT
STATIC_DEFINE ${LIBRARY_NAME_UPPER}_STATIC
)
if (ENABLE_TESTING)
message(STATUS "Building Library as Static Version for testing purpose")
add_library(${LIBRARY_NAME}_static STATIC ${${LIBRARY_NAME}_HDR} ${${LIBRARY_NAME}_SRC} ${${LIBRARY_NAME}_PRIVATE_HEADER})
target_include_directories(${LIBRARY_NAME}_static PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>"
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>")
set_target_properties(${LIBRARY_NAME}_static PROPERTIES VERSION ${${PROJECT_NAME}_VERSION}
PUBLIC_HEADER "${${LIBRARY_NAME}_HDR}")
string (TOUPPER ${LIBRARY_NAME} LIBRARY_NAME_UPPER)
set_target_properties(${LIBRARY_NAME}_static PROPERTIES COMPILE_FLAGS -D${LIBRARY_NAME_UPPER}_STATIC)
message(STATUS "Running Tests for the Library ${LIBRARY_TARGET_NAME}")
include(CTest)
add_subdirectory(tests)
endif()
For dependency Management i use Conan which works quite well.
And this is the CMakeLists.txt
File in the test
Folder:
set(TEST_TARGET_NAME ${PROJECT_NAME}_Test)
set(${TEST_TARGET_NAME}_SRC
my_libTest.cpp
StringHelperTest.cpp
TestRunner.cpp
)
add_executable(${TEST_TARGET_NAME} ${${TEST_TARGET_NAME}_SRC})
target_link_libraries(${TEST_TARGET_NAME} PRIVATE ${CONAN_LIBS_GTEST} FileInput_static)
add_test(NAME ${TEST_TARGET_NAME}
COMMAND ${TEST_TARGET_NAME}
WORKING_DIRECTORY $<TARGET_FILE_DIR:${TEST_TARGET_NAME}>)
target_include_directories(${TEST_TARGET_NAME} PRIVATE $<TARGET_PROPERTY:FileInput_static,INCLUDE_DIRECTORIES>)
Know my question is how to i test the Private Parts of my Library (e.g. the StringHelper.cpp/.h
contains Code which will not be exported.
My current solution is to add a second target and build the whole library as a Static
Library. And then in the Test Target link against it.
Is there maybe a better way on how to do such a task?
In Generall i would also be happy if someone could tell me if there are improvements to the CMakeLists.txt
files because i'm relatively new to CMake.