编写带校验的Makefile函数:十六进制转十进制并报错退出
Makefile实现带校验的十六进制转十进制函数
需求概述
需要实现一个可复用的Makefile函数,完成以下功能:
- 将输入的十六进制变量转换为十进制(处理bc对小写十六进制返回空的问题,自动转大写)
- 校验初始输入非空,为空则直接终止Make进程
- 校验转换结果非空,转换失败则终止Make进程
- 函数内部处理错误逻辑,无需每次调用后手动检查返回值
完整实现代码
# 定义带校验的十六进制转十进制函数 MyFunc = $(eval _input := $(strip $($(1)))) \ $(eval _result := $(shell \ # 校验输入非空 if [ -z "$(_input)" ]; then \ echo "Error: Variable '$(1)' cannot be empty!" >&2; \ exit 1; \ fi; \ # 执行十六进制转十进制,统一转大写(保留ibase小写) converted=$$(echo "ibase=16; $(_input)" | tr a-z A-Z | sed 's/IBASE/ibase/g' | bc); \ # 校验转换结果非空 if [ -z "$$converted" ]; then \ echo "Error: Failed to convert hex '$(_input)' to decimal (empty result)" >&2; \ exit 1; \ fi; \ echo "$$converted"; \ )) \ $(if $(_result),$(_result),$(error Conversion failed for variable '$(1)')) \ $(eval undefine _input) \ $(eval undefine _result) # 示例调用 MyVariable := 1A2B3C4D MyVariable := $(call MyFunc, MyVariable) # 测试目标 test: @echo Converted decimal value: $(MyVariable)
代码解释
函数参数处理:
$(1)是调用函数时传入的变量名,$($(1))获取该变量的实际值- 用
$(eval)定义临时变量_input和_result,避免重复执行shell命令
输入非空校验:
- 在shell脚本中通过
[ -z "$(_input)" ]判断输入是否为空,为空则输出错误信息到标准错误流(>&2)并返回非零退出码
- 在shell脚本中通过
十六进制转十进制:
- 通过
tr a-z A-Z将输入转为大写,再用sed 's/IBASE/ibase/g'把误转大写的ibase改回小写,确保bc能正确识别进制设置 - 调用
bc完成进制转换
- 通过
转换结果校验:
- 检查bc的输出是否为空,为空则输出错误信息并返回非零退出码
错误终止逻辑:
- 如果shell命令返回非零码,
$(shell ...)会返回空字符串,此时$(if $(_result),...)会触发$(error ...),直接终止Make进程 - 最后用
$(eval undefine)清理临时变量,避免污染全局命名空间
- 如果shell命令返回非零码,
测试场景
- 正常输入:运行
make test会输出转换后的十进制值439041101 - 空输入:若
MyVariable := "",Make会直接报错并退出 - 无效十六进制:若
MyVariable := GHIJ,bc返回空,Make会报错退出
内容的提问来源于stack exchange,提问作者user19804012
相关产品推荐
相关产品推荐

