admin管理员组文章数量:1025260
If I do this:
.PHONY: all
all: reports
reports : *.csv
@echo $^
make lists all the .CSV files in the directory on one line as expected. But when I do this:
.PHONY: all
all: reports
reports : %.csv
@echo $^
I get "*** No rules to make target '%.csv', needed for 'reports'. Stop.
I'm missing something basic. The .csv files are source for what I want the makefile to do to them. They are present in the directory. Why does make want to make them?
I was expecting make to take each .csv file in turn (using the %.csv) and for this example, echo out each file name. (The echo to be replaced with the actual commands later, of course), if I can understand how to pick up source that isn't a .c file.
If I do this:
.PHONY: all
all: reports
reports : *.csv
@echo $^
make lists all the .CSV files in the directory on one line as expected. But when I do this:
.PHONY: all
all: reports
reports : %.csv
@echo $^
I get "*** No rules to make target '%.csv', needed for 'reports'. Stop.
I'm missing something basic. The .csv files are source for what I want the makefile to do to them. They are present in the directory. Why does make want to make them?
I was expecting make to take each .csv file in turn (using the %.csv) and for this example, echo out each file name. (The echo to be replaced with the actual commands later, of course), if I can understand how to pick up source that isn't a .c file.
Share Improve this question asked Nov 18, 2024 at 22:19 Daniel EvansDaniel Evans 1 1- You haven't actually described what you really want to do here. Presumably when you say you want to print out each CSV file one at a time, you actually want to do something very different than just list the names of the files. Presumably you want to convert each CSV file into some other format or something like that. That's a very appropriate thing to do with make, and it's very easy. But since you didn't give us any information on this, such as for example the names of the files you wanted to generate with your converter, we can't give you an example of how to do it. – MadScientist Commented Nov 19, 2024 at 21:54
2 Answers
Reset to default 2I get "*** No rules to make target '%.csv', needed for 'reports'. Stop.
I'm missing something basic. The .csv files are source for what I want the makefile to do to them. They are present in the directory. Why does make want to make them?
To begin with, you're missing that make
does not want to build any of the existing files. The diagnostic says that it wants to build a file named exactly %.csv
. The "%
" there is a literal character. And it wants to build that file because you told it that that was a prerequisite for reports
, which it has decided it needs to build.
The broader picture seems to be that you are supposing that the %
serves as a general-purpose wildcard, equivalent to a *
in a glob expression. It does not, at least not in GNU make
or according to POSIX. GNU's implementation of make
does use that character for special purposes under some specific circumstances, but your example does not present any of those circumstances.
Possibly you are confusing your usage with a GNU make
"pattern rule", but pattern rules have a %
(exactly one) in the target, which is not the case in your rule for reports
. In a pattern rule, a %
in a prerequisite corresponds, with some caveats, to the same text that it did in the rule's target, for the target being considered. This allows GNU make
to match prerequisites to targets based on relationships between their names.
I was expecting make to take each .csv file in turn (using the %.csv) and for this example, echo out each file name.
Wanting to perform operations on arbitrary files smells like a scripting job. make
is not a script engine, and makefiles are not scripts. Make rules are not functions. If you want to write a script then do -- in Bash, or Python, or Perl, or whatever.
POSIX does not specify that shell wildcards have any significance to make
, nor does it specify any other analogous mechanism, so portable shell scripts can't do what you describe. However, some implementations, notably GNU's, do recognize shell wildcards, as you discovered, so if you're willing to constrain yourself to make
implementations with that property then you already know how to achieve what you ask.
As I said in my comment we don't have enough detail to help you directly. But, let's suppose what you want to do is convert every .csv
file into a .out
file using sometool
that takes input from stdin and writes to stdout, then combine all of the .out
files using cat
.
You can do it like this:
# get a list of all CSV files
CSV_FILES := $(wildcard *.csv)
# derive a list of .out filenames
OUT_FILES := $(CSV_FILES:%.csv=%.out)
all: report
# the report target depends on all the .out files
report: $(OUT_FILES)
cat $^ > $@
# teach make how to convert a single CSV file into a single .out file
%.out : %.csv
sometool < $< > $@
If I do this:
.PHONY: all
all: reports
reports : *.csv
@echo $^
make lists all the .CSV files in the directory on one line as expected. But when I do this:
.PHONY: all
all: reports
reports : %.csv
@echo $^
I get "*** No rules to make target '%.csv', needed for 'reports'. Stop.
I'm missing something basic. The .csv files are source for what I want the makefile to do to them. They are present in the directory. Why does make want to make them?
I was expecting make to take each .csv file in turn (using the %.csv) and for this example, echo out each file name. (The echo to be replaced with the actual commands later, of course), if I can understand how to pick up source that isn't a .c file.
If I do this:
.PHONY: all
all: reports
reports : *.csv
@echo $^
make lists all the .CSV files in the directory on one line as expected. But when I do this:
.PHONY: all
all: reports
reports : %.csv
@echo $^
I get "*** No rules to make target '%.csv', needed for 'reports'. Stop.
I'm missing something basic. The .csv files are source for what I want the makefile to do to them. They are present in the directory. Why does make want to make them?
I was expecting make to take each .csv file in turn (using the %.csv) and for this example, echo out each file name. (The echo to be replaced with the actual commands later, of course), if I can understand how to pick up source that isn't a .c file.
Share Improve this question asked Nov 18, 2024 at 22:19 Daniel EvansDaniel Evans 1 1- You haven't actually described what you really want to do here. Presumably when you say you want to print out each CSV file one at a time, you actually want to do something very different than just list the names of the files. Presumably you want to convert each CSV file into some other format or something like that. That's a very appropriate thing to do with make, and it's very easy. But since you didn't give us any information on this, such as for example the names of the files you wanted to generate with your converter, we can't give you an example of how to do it. – MadScientist Commented Nov 19, 2024 at 21:54
2 Answers
Reset to default 2I get "*** No rules to make target '%.csv', needed for 'reports'. Stop.
I'm missing something basic. The .csv files are source for what I want the makefile to do to them. They are present in the directory. Why does make want to make them?
To begin with, you're missing that make
does not want to build any of the existing files. The diagnostic says that it wants to build a file named exactly %.csv
. The "%
" there is a literal character. And it wants to build that file because you told it that that was a prerequisite for reports
, which it has decided it needs to build.
The broader picture seems to be that you are supposing that the %
serves as a general-purpose wildcard, equivalent to a *
in a glob expression. It does not, at least not in GNU make
or according to POSIX. GNU's implementation of make
does use that character for special purposes under some specific circumstances, but your example does not present any of those circumstances.
Possibly you are confusing your usage with a GNU make
"pattern rule", but pattern rules have a %
(exactly one) in the target, which is not the case in your rule for reports
. In a pattern rule, a %
in a prerequisite corresponds, with some caveats, to the same text that it did in the rule's target, for the target being considered. This allows GNU make
to match prerequisites to targets based on relationships between their names.
I was expecting make to take each .csv file in turn (using the %.csv) and for this example, echo out each file name.
Wanting to perform operations on arbitrary files smells like a scripting job. make
is not a script engine, and makefiles are not scripts. Make rules are not functions. If you want to write a script then do -- in Bash, or Python, or Perl, or whatever.
POSIX does not specify that shell wildcards have any significance to make
, nor does it specify any other analogous mechanism, so portable shell scripts can't do what you describe. However, some implementations, notably GNU's, do recognize shell wildcards, as you discovered, so if you're willing to constrain yourself to make
implementations with that property then you already know how to achieve what you ask.
As I said in my comment we don't have enough detail to help you directly. But, let's suppose what you want to do is convert every .csv
file into a .out
file using sometool
that takes input from stdin and writes to stdout, then combine all of the .out
files using cat
.
You can do it like this:
# get a list of all CSV files
CSV_FILES := $(wildcard *.csv)
# derive a list of .out filenames
OUT_FILES := $(CSV_FILES:%.csv=%.out)
all: report
# the report target depends on all the .out files
report: $(OUT_FILES)
cat $^ > $@
# teach make how to convert a single CSV file into a single .out file
%.out : %.csv
sometool < $< > $@
本文标签: Basic makefile question involving the use of quotquotStack Overflow
版权声明:本文标题:Basic makefile question involving the use of "%" - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745590659a2157864.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论