Best/Shortest way to join a list in CMake

前端 未结 4 483
温柔的废话
温柔的废话 2021-02-04 06:07

What is the best way to join a list in CMake into a string?

By joining I mean convert SET(somelist \"a\" \"b\" \"c\\;c\") to \"a:b:c;c\" where the glue string (\":\") i

相关标签:
4条回答
  • 2021-02-04 06:18

    Usually this task is solved with simple string REPLACE command. You can find a number of such replaces in scripts coming with cmake. But if you really need to care about semicolons inside you values, then you can use the following code:

    function(JOIN VALUES GLUE OUTPUT)
      string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
      string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
      set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
    endfunction()
    
    SET( letters "" "\;a" b c "d\;d" )
    JOIN("${letters}" ":" output)
    MESSAGE("${output}") # :;a:b:c:d;d
    
    0 讨论(0)
  • 2021-02-04 06:18

    CMake 3.12 is poised to finally add this upstream:

    https://github.com/Kitware/CMake/commit/a58158727be4585f9fd71449e9cc9e801c59a009

    https://github.com/Kitware/CMake/commit/689eeb67cb87a9ed1d91a4971806488d00e68f42

    0 讨论(0)
  • 2021-02-04 06:18

    You can use the string REPLACE function:

    function(JOIN VALUES GLUE OUTPUT)
      string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
      set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
    endfunction()
    
    #USAGE:
    SET(somelist a b c)
    JOIN("${somelist}" ":" output)
    MESSAGE("${output}") # will output "a:b:c"
    
    0 讨论(0)
  • 2021-02-04 06:31

    The answers above are ok, when you do not use semicolons or when you can (and want to) escape them. I prefer not to escape semicolons, so I wrote the following function:

    function(JOIN OUTPUT GLUE)
        set(_TMP_RESULT "")
        set(_GLUE "") # effective glue is empty at the beginning
        foreach(arg ${ARGN})
            set(_TMP_RESULT "${_TMP_RESULT}${_GLUE}${arg}")
            set(_GLUE "${GLUE}")
        endforeach()
        set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE)
    endfunction()
    

    The advantage is that the list can be empty and it doesn't have to be in a variable (but may be written in the place of invocation).

    The usage is:

    set(SOME_LIST a b c d)
    join(RESULT "/" ${SOME_LIST})
    message(STATUS "RESULT='${RESULT}'") # outputs RESULT='a/b/c/d'
    # or
    join(RESULT " " e f g h)
    message(STATUS "RESULT='${RESULT}'") # outputs RESULT='e f g h'
    
    0 讨论(0)
提交回复
热议问题