go - 尽管存在目标,但始终执行 Makefile 规则
问题描述
我正在尝试调整我Makefile
的GoLang 项目。我有几条规则应该:
- 设置一个 git pre-commit 钩子(不想提交二进制文件并意外违反版权法)
- 通过以下方式下载 mp3 文件
youtube-dl
- 通过以下方式提取该视频的一部分
ffmpeg
以前我是通过 shellscript 执行此操作并手动检查每个文件,但在将我的脚本转换为 Makefile 的过程中,我似乎遗漏了一些东西。
唯一不会重新运行的规则是 pre-hook,但我认为这是因为我没有为我的目标/规则名称使用变量?
.default: install
.phony: install generate clean
export bin_directory = bin
export asset_directory = data/assets
export song_url = https://www.youtube.com/watch?v=z8cgNLGnnK4
export song_file = ${bin_directory}/nsp-you-spin-me-cover.mp3
export loop_file = ${asset_directory}/spin-loop.mp3
install:
go install .
generate: $(loop_file)
go generate ./data
$(loop_file): $(song_file)
mkdir -p "${asset_directory}"
ffmpeg -i "${song_file}" -ss 00:01:13.30 -to 00:01:30.38 -c copy "${loop_file}"
$(song_file): .git/hooks/pre-commit
mkdir -p "${bin_directory}"
youtube-dl "${song_url}" --extract-audio --audio-format mp3 --exec "mv {} ${song_file}"
.git/hooks/pre-commit:
cp ./pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
clean:
git clean -xdf
更新:如果我generate
像这样将所有依赖项集中到规则中,我发现这可以正常工作(这似乎是错误的做法)
.default: install
.phony: install generate clean
bin_directory:=bin
asset_directory:=data/assets
song_url:=https://www.youtube.com/watch?v=z8cgNLGnnK4
song_file:=$(bin_directory)/nsp-you-spin-me-cover.mp3
loop_file:=$(asset_directory)/spin-loop.mp3
install:
go install .
.git/hooks/pre-commit:
cp ./pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
$(song_file):
mkdir -p "${bin_directory}"
youtube-dl "${song_url}" --extract-audio --audio-format mp3 --exec "mv {} ${song_file}"
$(loop_file):
mkdir -p "${asset_directory}"
ffmpeg -i "${song_file}" -ss 00:01:13.30 -to 00:01:30.38 -c copy "${loop_file}"
generate: .git/hooks/pre-commit $(song_file) $(loop_file)
go generate ./data
clean:
git clean -xdf
解决方案
您没有指定,但我假设您在make generate
看到此行为时正在运行。如果您显示您键入的命令、您获得的输出(剪切和粘贴并正确格式化)或至少足以看到问题,并准确指出输出的哪一部分是意外的以及什么,那么在提问时总是最好的你预计会发生。
假设上面准确描述了您的环境和 makefile,那么您所看到的行为的最明显原因是此命令:
youtube-dl "${song_url}" --extract-audio --audio-format mp3 --exec "mv {} ${song_file}"
没有更新输出文件上的时间戳$(song_file)
,所以它看起来总是比依赖它的目标更老,所以 make 总是重建它。
运行 makefile 后,ls -l
对所有预期的输出文件使用并查看它们的修改时间是否已更新。如果不是,您可能需要touch $@
在命令之后添加到您的规则youtube-dl
,以确保它已更新:
$(song_file): .git/hooks/pre-commit
mkdir -p "${@D}"
youtube-dl "${song_url}" --extract-audio --audio-format mp3 --exec "mv {} $@"
touch $@
同样如上述评论中所述,以及 GNU make 文档中所述,特殊目标是.DEFAULT
(大写) 和.PHONY
(大写),而不是.default
and .phony
。后者只是您定义的目标,就像foo
或其他一样;它们对 GNU make 没有特殊意义。像所有 UNIX/POSIX 工具和语言一样,makefile 是区分大小写的,因此请小心为 GNU make 手册中描述的关键字使用正确的大小写(以及您在 makefile 中定义的目标)
删除export
不会改变任何东西:GNU make 允许在同一行上分配和导出变量。
推荐阅读
- sql - Oracle SQL - 按每日、每周和每月汇总和分组数据。(缺少日期、星期和月份)
- android - 如何让搜索栏自动在录音机上移动?
- android - Expo - 使用“应用签名”证书构建 android app-bundle
- karate - 尝试在 Gatling 中运行空手道功能时出现超时异常
- python - 找到几个单词,如果删除一个字母将打印这两个单词
- ruby-on-rails - 如何在法拉第启用日志记录机构
- java - 反应原生 Amplify AWS 包与火力库冲突
- node.js - 从 mongodb 中的数组中提取数据,如果数据超过 10 分钟且临时为真
- sql - 获取薪水第二高的员工姓名
- firebase - 如何通过异步调用 uid 从 Firebase 查询数据