Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake testing a library, header location issue

So, I'm making part of a project a library with some headers that are the interface to the library, and the remaining are private to the library itself. So for my library the CMAKE part looks like:

add_library(${PROJECT_NAME} ${PROJECT_SOURCES} "${PROJECT_BINARY_DIR}/libversion.h")
add_library(my::lib ALIAS ${PROJECT_NAME})

target_include_directories(${PROJECT_NAME} 
    PRIVATE ${Boost_INCLUDE_DIRS}
    PRIVATE ${PROJECT_BINARY_DIR} #to locate libversion.h
    INTERFACE ${PUBLIC_INCLUDE_HEADERS}
    )

And then my test target:

add_executable(${TEST_NAME} ${TEST_SOURCES})
add_test(NAME LibTest COMMAND ${TEST_NAME})

target_link_libraries(${TEST_NAME} 
    PRIVATE ${Boost_LIBRARIES}
    PRIVATE my::lib
    )

But this only allows me to test my public interface. If I want to unit test my library, how would I go about declaring the access to the remaining headers in project lib? The way I see it would be to add an entire new target my::lib::testing which declares the interface as the current source directory (where all headers currently are located, seperating public from private headers is another issue I've yet to handle). So something like this:

add_library(${PROJECT_NAME}_TESTING ${PROJECT_SOURCES} "${PROJECT_BINARY_DIR}/libversion.h")
add_library(my::lib::testing ALIAS ${PROJECT_NAME}_TESTING)

target_include_directories(${PROJECT_NAME}_TESTING
    PRIVATE ${Boost_INCLUDE_DIRS}
    PRIVATE ${PROJECT_BINARY_DIR} #to locate libversion.h
    INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
    )

But this requires two different targets to be build depending on the usage. One for my application linking to alias my::lib and one for unit testing, linking alias my::lib::testing.

So my question is, how do I cleanly separate headers so I can have only my INTERFACE headers shown by targets, but still access the remaining headers by my test target?

like image 486
Sheph Avatar asked Feb 13 '16 22:02

Sheph


1 Answers

Both PRIVATE and PUBLIC items populate the INCLUDE_DIRECTORIES property of an target, so you can try to use it in target_include_directories for the test project.

add_executable(${TEST_NAME} ${TEST_SOURCES})
add_test(NAME LibTest COMMAND ${TEST_NAME})

target_link_libraries(${TEST_NAME} 
    PRIVATE ${Boost_LIBRARIES}
    PRIVATE my::lib
    )

target_include_directories( ${TEST_NAME} PRIVATE $<TARGET_PROPERTY:my::lib,INCLUDE_DIRECTORIES>)
like image 187
anna Avatar answered Nov 15 '22 03:11

anna