CMake函数中输入列表无法更新的问题排查
问题分析与解决方案
你遇到的问题核心在于CMake函数参数传递的方式,以及如何正确修改父作用域的变量。
为什么原代码不生效?
当你调用prepend_number("${numbers}")时,你是把numbers变量的值(也就是one;two;three;four;five)传递给了函数的_input_list参数,而不是传递变量名numbers。
函数里这一行:
set(${_input_list} "${_new_list}" PARENT_SCOPE)
实际上是在尝试创建一个名为one;two;three;four;five的变量(因为${_input_list}展开后就是这个字符串),这显然不是你想要的——你真正想修改的是父作用域里的numbers变量,而不是这个奇怪的“变量名”。
另外,函数内部的message(STATUS "Revised input: ${_input_list}")输出的还是原来传入的列表值,因为_input_list本身在函数作用域里没有被修改,你只是尝试修改了一个不存在的变量。
修改后的正确代码
我们需要调整函数的参数传递方式,让它接收变量名而非变量的值,这样才能正确地修改父作用域里的目标变量:
function(prepend_number _var_name) # 获取父作用域中变量的值 set(_input_list "${${_var_name}}") set(_new_list "") foreach(_item ${_input_list}) list(APPEND _new_list "number_${_item}") endforeach() message(STATUS "Input: ${_input_list}") message(STATUS "Amended list: ${_new_list}") # 将新列表赋值给父作用域的目标变量 set(${_var_name} "${_new_list}" PARENT_SCOPE) endfunction() set(numbers one two three four five) prepend_number(numbers) # 这里直接传变量名,不要加引号和${} message(STATUS "Final numbers: ${numbers}")
执行效果
运行这段代码后,你会得到如下输出:
Input: one;two;three;four;five Amended list: number_one;number_two;number_three;number_four;number_five Final numbers: number_one;number_two;number_three;number_four;number_five
额外优化(可选)
如果想让函数更通用,支持自定义前缀,可以再加一个参数:
function(prepend_prefix _var_name _prefix) set(_input_list "${${_var_name}}") set(_new_list "") foreach(_item ${_input_list}) list(APPEND _new_list "${_prefix}${_item}") endforeach() set(${_var_name} "${_new_list}" PARENT_SCOPE) endfunction() set(numbers one two three four five) prepend_prefix(numbers "number_") message(STATUS "Final numbers: ${numbers}")
这样函数就可以灵活处理不同的前缀需求了。
内容的提问来源于stack exchange,提问作者Sciapod
相关产品推荐
相关产品推荐

