英文:
"No rule to make target" with % in Makefile Error
问题
我正在编写我的第一个Makefile。在其中,我希望将所有在名为FOLDER/assets
的文件夹中已更新的文件复制到FOLDER/export_bin/application/assets
中。我一直在使用https://makefiletutorial.com/ 作为参考。
以下是我为此编写的代码:
build_game:
$(MAKE) $(export_folder)/application/assets/%
...
$(export_folder)/application/assets/%: ../assets/%
cp $@ $<
我遇到了错误:
make[1]: *** No rule to make target 'debug/application/assets/%'. Stop.
我应该如何改进这个问题?
英文:
I am writing my first Makefile. In it, I want all files that have been updated in a folder called FOLDER/assets
to be copied to FOLDER/export_bin/application/assets
. I've been using https://makefiletutorial.com/ as a reference.
Here's the code I wrote for it:
build_game:
$(MAKE) $(export_folder)/application/assets/%
...
$(export_folder)/application/assets/%: ../assets/%
cp $@ $<
I get the error:
make[1]: *** No rule to make target 'debug/application/assets/%'. Stop.
How should I do this instead?
答案1
得分: 1
这里是翻译后的代码部分:
base := FOLDER
export_folder := $(base)/export_bin
import_folder := $(base)/assets
input_files := $(wildcard $(import_folder)/*)
# 请参阅 https://makefiletutorial.com/#string-substitution
output_files := $(patsubst $(import_folder)/%,$(export_folder)/application/assets/%,$(input_files))
# 请参阅 https://makefiletutorial.com/#phony
.PHONY: build_game
build_game: $(output_files)
$(export_folder)/application/assets/%: $(import_folder)/%
cp $< $@
以上是您提供的代码的翻译部分,没有包含其他内容。如果您需要进一步的帮助,请随时提问。
英文:
Here you go:
base := FOLDER
export_folder := $(base)/export_bin
import_folder := $(base)/assets
input_files := $(wildcard $(import_folder)/*)
# See https://makefiletutorial.com/#string-substitution
output_files := $(patsubst $(import_folder)/%,$(export_folder)/application/assets/%,$(input_files))
# See https://makefiletutorial.com/#phony
.PHONY: build_game
build_game: $(output_files)
$(export_folder)/application/assets/%: $(import_folder)/%
cp $< $@
The first few lines set up the directories we will be using. The key line is the input_files
assignment calling $(wildcard)
. (This is a GNU extension.) The tutorial you went to doesn't appear to cover this feature.
Then we construct the output file list by substituting the import paths for the output path. The .PHONY:
pseudo-target indicates that build_game
is not intended to be a real file; otherwise make
can get confused. We make the build_game
target dependent on the output files; this triggers the rules for making the output files at the end. Finally we have the output file rule; it's essentially the same as what you used, except you swapped the $<
and $@
and used a relative path, which might work but I wouldn't recommend it.
答案2
得分: 0
asset_files := %(notdir $(wildcard ../assets))
target_asset_files := $(addprefix $(export_folder)/application/assets/,$(asset_files))
build_game : $(target_asset_files)
$(export_folder)/application/assets/%: ../assets/%
cp $@ $<
asset_src := ../assets
asset_trg := $(export_folder)/application/assets
build_game : rsync_sentinel
rsync_sentinel: $(wildcard $(asset_src)/*)
rsync -a --delete $(asset_src)/ $(asset_trg)
touch $@
这些是你提供的两个Makefile代码片段,用于处理资产文件的复制和同步。
英文:
asset_files := %(notdir $(wildcard ../assets))
target_asset_files := $(addprefix $(export_folder)/application/assets/,$(asset_files))
build_game : $(target_asset_files)
$(export_folder)/application/assets/%: ../assets/%
cp $@ $<
build_game
is dependent on all the asset files, which will get copied over via the pattern rule if they are out of date.
One sharp stick here is that if you delete a file in the source directory (../assets/
), it would not be deleted in the target directory, so your target directory will not necessarily be in sync with the source... If you need the two to be in sync, there's other ways to do that.
------ EDIT ---------
to use rsync, you would do something to this effect:
asset_src := ../assets
asset_trg := $(export_folder)/application/assets
build_game : rsync_sentinel
rsync_sentinel: $(wildcard $(asset_src)/*)
rsync -a --delete $(asset_src)/ $(asset_trg)
touch $@
Here, the sentinel file is a dummy file whos timestamp represents the last time it did a copy. If any of the files inside ../assets
is newer than the sentinel, it will use rsync to copy any necessary files over, and then update the timestamp of the sentinel.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论