You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Makefile中所有变量及其值写入文件?

Makefile变量输出到文件的问题与解决

原需求与工作代码

我需要用Makefile获取所有变量及其值并写入文件,目前有一段代码可以在终端打印出变量,但无法将输出重定向到文件:

.PHONY: test
test:
    $(foreach v,                                        \
          $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
          $(info $(v) = $($(v))))

无效的尝试

我试了几种方法都无法将输出写入文件:

  • 直接在info后加重定向:...$(info $(v) = $($(v)))) > myfile.txt
  • 追加模式重定向:...$(info $(v) = $($(v))) >> myfile.txt)
  • 尝试用变量存储所有输出后写入:
ALL_MAKEFILE_VARS:; $(foreach v, $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), $(info $(v)=$($(v))))
.PHONY: test
test:
    $(file > myfile.txt,$(ALL_MAKEFILE_VARS))
  • 用echo包裹输出重定向:echo -e $(foreach v, $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), $(info $(v)=$($(v)))) > derp.txt

使用file函数遇到的新问题

问题1:提示"Nothing to be done for 'test'"

尝试用file函数写入文件时,执行make test会提示该信息,对应的代码:

VARS_OLD:= $(.VARIABLES)
.PHONY: test
test:
    $(foreach v,                                        \
          $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
          $(file >myfile.txt,$(v) = $($(v))))

问题2:移除VARS_OLD后报错且文件内容不完整

去掉VARS_OLD:= $(.VARIABLES)后,执行报错:

*** Undefined  required by target `test`.  Stop

虽然生成了myfile.txt,但文件里只有一行内容:

.LIBPATTERNS = lib%.dylib lib%.a
解决方案

核心问题分析

  1. $(file >myfile.txt,...)每次调用都会清空文件再写入,循环结束后只会保留最后一个变量的内容,需要改用追加模式$(file >>myfile.txt,...)。
  2. VARS_OLD:= $(.VARIABLES)用立即展开赋值时,会在Makefile解析阶段就把.VARIABLES的内容赋值给VARS_OLD,导致后续filter-out把所有变量都过滤掉,foreach没有生成任何执行命令,因此make认为test目标无操作。
  3. 移除VARS_OLD后,filter-out $(VARS_OLD) VARS_OLD变成空参数加VARS_OLD,导致filter-out行为异常,生成无效变量名引发报错。

正确写法1:通过Shell重定向输出

直接在目标命令中用foreach生成echo语句,整体重定向到文件:

.PHONY: test
test:
    @$(foreach v, $(filter-out VARS_OLD,$(.VARIABLES)), echo "$(v) = $($(v))";) > myfile.txt
  • @用于隐藏命令本身的输出
  • 用echo输出每个变量,整体重定向避免循环中多次打开文件
  • 如果变量包含特殊字符,"$(v) = $($(v))"的引号可以保证输出格式正确

正确写法2:使用file函数追加并延迟变量展开

改用递归展开变量定义VARS_OLD,确保foreach在执行阶段才展开变量,同时先清空文件再追加:

.PHONY: test
test:
    $(file >myfile.txt,)  # 先清空文件
    $(foreach v, $(filter-out VARS_OLD,$(.VARIABLES)), \
        $(file >>myfile.txt,$(v) = $($(v))))
VARS_OLD = $(.VARIABLES)
  • VARS_OLD = $(.VARIABLES)是递归展开,会在foreach执行时才获取当前的.VARIABLES内容
  • $(file >myfile.txt,)清空文件,避免多次运行时内容累加
  • >>模式保证每个变量内容都追加到文件中

内容的提问来源于stack exchange,提问作者red888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 11:47:45