Makefile中编写数值表达式解决Podman UID/GID映射计算失效问题
问题原因
Makefile 采用独立的变量解析规则,不会原生支持Bash的$(( ))算术语法:
- 直接写在Make变量定义中的
$(($uid+1))这类表达式,会被Make优先识别为自身的变量引用,其中$u、$+这类不存在的Make变量会被直接替换为空字符串,最终传给执行层的内容是非法表达式,自然返回空值。 - 原有
subuidSize、subgidSize的计算逻辑存在两层错误:一是shell算术表达式多嵌套了一层括号,二是podman命令输出的字符串以+开头,直接参与算术运算会触发语法错误。
修复方法
所有算术计算统一通过$(shell )交给Bash执行,注意Makefile中传给shell的$符号必须写为$$做转义,避免被Make提前解析;建议提前把所有需要计算的数值存为独立Make变量,避免在长命令中混杂算术逻辑引发转义错误。
另外所有Make目标下的执行命令必须使用Tab缩进,不能用空格替代。
修复后的完整Makefile内容如下:
HOST_GEM5 := /mnt/disk/cuiyujie/workspace/workGem5/gem5 SIM := ${HOST_GEM5}/X86/gem5.opt SHELL := /bin/bash DOCKER_GEM5 := /usr/local/src/gem5 # 提前计算subuid/subgid总大小,处理podman输出前缀+的问题 subuidSize := $(shell s=$$(podman info --format "{{ range .Host.IDMappings.UIDMap }}+{{.Size }}{{end }}"); echo $$(($${s:1} - 1))) subgidSize := $(shell s=$$(podman info --format "{{ range .Host.IDMappings.GIDMap }}+{{.Size }}{{end }}"); echo $$(($${s:1} - 1))) uid := $(shell id -u) gid := $(shell id -g) # 提前计算UID/GID映射需要的所有算术值,避免后续转义错误 uid_map_start := $(shell echo $$(($(uid) + 1))) gid_map_start := $(shell echo $$(($(gid) + 1))) uid_map_count := $(shell echo $$(($(subuidSize) - $(uid)))) gid_map_count := $(shell echo $$(($(subgidSize) - $(gid)))) DOCKER_DIRS_MAP := \ -v ${HOST_GEM5}/runScripts:${DOCKER_GEM5}/runScripts MAP_CMD := \ --user ${uid}:${gid} \ --uidmap ${uid}:0:1 \ --uidmap 0:1:${uid} \ --uidmap ${uid_map_start}:${uid_map_start}:${uid_map_count} \ --gidmap ${gid}:0:1 \ --gidmap 0:1:${gid} \ --gidmap ${gid_map_start}:${gid_map_start}:${gid_map_count} .PHONY: default clean run build default: build build: podman run -it --rm ${DOCKER_DIRS_MAP} --security-opt seccomp=unconfined \ ${MAP_CMD} \ gerrie/gem5:v1 "/bin/bash" clean: rm -rf ${HOST_GEM5}/build/*
验证方式
修改完成后可以执行make -n build预览实际执行的podman命令,检查UID/GID映射的参数是否为正确的数值,没有空值即可正常使用。
内容的提问来源于stack exchange,提问作者Gerrie
相关产品推荐
相关产品推荐

