2

I followed this and this link to write a function that:

  • takes a list of files as input,
  • appends path to each file
  • Creates a new list (passed as an output parameter to the function itself) by appending all the files to it

    function(concat_path iLiItems oLiItems cVal) 
      foreach(pfile ${${iLiItems}})
        string(CONCAT l ${${cVal}} ${pfile})
        message(STATUS ${pfile} " - " ${l})
        set(${oLiItems} ${${oLiItems}} ${l} PARENT_SCOPE)
      endforeach()
    endfunction()
    
    function(list_print liItems)
        message(STATUS "The list contains: ")
      foreach(f ${${liItems}})
        message(STATUS ${f})
      endforeach()
    endfunction()
    
    set(PROTO_SRCS base.proto dht.proto)
    
    foreach(pfile ${PROTO_SRCS}) 
      string(REPLACE ".proto" ".pb" fname ${pfile})
      string(CONCAT cc ${fname} ".cc")
      string(CONCAT h ${fname} ".h")
      set(PROTO_CPP_SRCS ${PROTO_CPP_SRCS} ${cc} ${h})
    endforeach()
    
    string(CONCAT path_prefix ${CMAKE_CURRENT_SOURCE_DIR} "/")
    concat_path(PROTO_SRCS PROTO_SRCS_PATH path_prefix)
    list_print(PROTO_SRCS_PATH)
    

The problem I see is that when I finally print using the function, "list_print" i see that only one element is present in the output list (PROTO_SRCS_PATH) where as I was expecting two corresponding to both the input files:

-- base.proto - C:/Users/vaddina/workspace/protobuf-tests/app-wo-findprotobuf/base.proto
-- dht.proto - C:/Users/vaddina/workspace/protobuf-tests/app-wo-findprotobuf/dht.proto
-- The list contains:
-- C:/Users/vaddina/workspace/protobuf-tests/app-wo-findprotobuf/dht.proto

What am I doing wrong ? Thank you.

lightsunray
  • 409
  • 5
  • 16

1 Answers1

4

With PARENT_SCOPE option you change value of variable in the parent scope, but a variable in the current scope is unchanged. This is explicitely descrbed in the documentation about PARENT_SCOPE:

This command will set the value of a variable into the parent directory or calling function (whichever is applicable to the case at hand). The previous state of the variable’s value stays the same in the current scope (e.g., if it was undefined before, it is still undefined and if it had a value, it is still that value).

Because of that, the call to

set(${oLiItems} ${${oLiItems}} ${l} PARENT_SCOPE)

always see empty value as the second argument (you never assign the variable in the current scope). So the variable in the parent scope is always assigned (not appended!) by ${l}.

Normally, setting a variable with PARENT_SCOPE is performed only once. Intermediate calculation should use and update variable in the current scope:

function(concat_path iLiItems oLiItems cVal) 
  foreach(pfile ${${iLiItems}})
    string(CONCAT l ${${cVal}} ${pfile})
    message(STATUS ${pfile} " - " ${l})
    set(${oLiItems} ${${oLiItems}} ${l}) # Update list in the current scope only
  endforeach()
  # Before return, propagate variable's value to the parent scope.
  set(${oLiItems} ${${oLiItems}} PARENT_SCOPE)
endfunction()
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153