Makefile执行make clean时报syntax error near unexpected token '('错误如何解决
问题根因
- Make 默认使用
/bin/sh作为执行命令的shell,绝大多数发行版中/bin/sh不支持bash专属的shopt命令和extglob扩展通配符语法,所以识别不了!(*.sv|*svh|"makefile")这种写法,会报括号语法错误 - Make中目标下的每行命令默认是独立的shell进程,即使当前环境是bash,上一行执行的
shopt -s extglob仅对该行进程生效,下一行执行rm时配置已经失效
解决方案
你可以任选以下一种方案修复:
方案1:适配bash扩展特性
在Makefile开头指定使用bash作为执行shell,同时将clean的命令合并到同一shell进程执行即可,另外你原Makefile开头的#!/bin/bash对Makefile无效,可以直接删除。
修改后示例:
# 指定Make使用bash执行命令 SHELL := /bin/bash # Example: # make run TEST_CASE="testbench.sv" # make clean compile: vcs $(TEST_CASE) -sverilog; run: compile ./simv uvm_compile: vcs $(TEST_CASE) -sverilog; clean: # 两行命令用分号连接,保证extglob配置对rm生效 shopt -s extglob; rm -v !(*.sv|*svh|makefile)
如果你使用的GNU Make版本在3.82以上,也可以用.ONESHELL配置让同一个目标下的所有命令跑在同一个shell进程,写法更清晰:
SHELL := /bin/bash .ONESHELL: # 其他内容不变 clean: shopt -s extglob rm -v !(*.sv|*svh|makefile)
方案2:使用POSIX兼容写法(兼容性更好)
如果不想依赖bash特性,可以用通用的find命令实现相同的清理逻辑,不需要修改默认shell:
clean: # 仅删除当前目录下非.sv/.svh/makefile的文件,不递归子目录,打印删除日志 find . -maxdepth 1 -type f ! -name "*.sv" ! -name "*.svh" ! -name "makefile" -delete -print
内容的提问来源于stack exchange,提问作者Toby Liao
相关产品推荐
相关产品推荐

