CMake: how to add Boost.Test cases with relative directories?

后端 未结 2 814
旧时难觅i
旧时难觅i 2020-12-10 07:05

I have a working project with CMake and Boost.Test with a directory structure like this (pardon the ASCII art):

+-proj
|---CMakeLists.txt
|---build
|---test
         


        
相关标签:
2条回答
  • 2020-12-10 07:44

    It is possible to specify a RELATIVE flag and a directory to a file( GLOB ... ) command. Although not mentioned directly in the documentation of file( GLOB ), this works for file( GLOB_RECURSE ... ) too. Note, I tested this on my windows setup. I don't known about *nix.

    1. Together with some get_filename_component calls with NAME_WE and/or PATH flags, it is now possible to reconstruct the name and the relative path of the cpp-file with respect to the globbing dir.
    2. Extracting a path and a name (without extension) is mostly similar to the answer by Massimiliano. In addition, I have used his suggestion to generate a unique testname with string( REGEX REPLACE ... ); replacing forward slashes by underscores.
    3. With a unique test-name, the executable can be generated and afterwards its output directory can be modified with set_target_properties.

    Check this and this question for more info on modifying the output directory.

    file( GLOB_RECURSE TEST_CPP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
    
    foreach( test_case ${TEST_CPP_SOURCES} )
        # Get the name without extension
        get_filename_component( test_name ${test_case} NAME_WE )
        # Get the path to the test-case, relative to the ${CMAKE_CURRENT_SOURCE_DIR} 
        # thanks to the RELATIVE flag in file( GLOB_RECURSE ... )
        get_filename_component( test_path ${test_case} PATH )
    
        message( STATUS "  name = " ${test_name} )
        message( STATUS "  path = " ${test_path} )
        # I would suggests constructing a 'unique' test-name
        string( REPLACE "/" "_" full_testcase "${test_name}/${test_path}" )
    
        # Add an executable using the 'unique' test-name
        message( STATUS "  added " ${full_testcase} " in " ${test_path} )
        add_executable( ${full_testcase} ${test_case} )
        # and modify its output paths. 
        set_target_properties( ${full_testcase} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${test_path} )
    endforeach( test_case ${TEST_CPP_SOURCES} )
    
    0 讨论(0)
  • 2020-12-10 07:47

    A possible solution to disambiguate names in a directory structure like the one you have using a FOREACH() over ${test_cases} may be:

    # Set Cmake version and policy
    CMAKE_MINIMUM_REQUIRED( VERSION 2.8.7 )
    CMAKE_POLICY( VERSION 2.8.7 )
    
    PROJECT( DUMMY CXX )
    
    FILE( GLOB_RECURSE test_cases FOLLOW_SYMLINKS "test/*.[h,c]pp" )
    
    FOREACH( case ${test_cases} )
      ## Get filename without extension
      GET_FILENAME_COMPONENT(case_name_we ${case} NAME_WE)
      ## Get innermost directory name
      GET_FILENAME_COMPONENT(case_directory ${case} PATH)
      GET_FILENAME_COMPONENT(case_innermost ${case_directory} NAME_WE)
      ## Construct executable name
      SET( exe_name "${case_innermost}_${case_name_we}")
      ## Construct test name
      SET( test_name "${exe_name}_test")
      ## Add executable and test
      ADD_EXECUTABLE( ${exe_name} ${case} )
      ADD_TEST( ${test_name} ${exe_name} )
    ENDFOREACH()
    

    As you can see this CMakeLists.txt creates 4 distinct test/executable couples.

    0 讨论(0)
提交回复
热议问题