“No rule to make target” 在 Makefile 中出现的错误,带有 % 符号。

huangapple go评论79阅读模式
英文:

"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 $@ $&lt;

I get the error:

make[1]: *** No rule to make target &#39;debug/application/assets/%&#39;.  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 $&lt; $@

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 $&lt; 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 $@ $&lt;

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.

huangapple
  • 本文由 发表于 2023年7月7日 00:34:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76630896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定