This question already has answers here:
What do #, - and + do as prefixes to recipe lines in Make?
(2 answers)
Closed 4 years ago.
In a few makefiles, I came across #rm syntax, vs -rm (ignore errors thrown by rm) and pure rm.
I'd like to know what's the difference.
# tells make to not echo the recipe to output when it's run.
- tells make to ignore the return value of the recipe (assume it passes)
you can use a combination of both of these and +. See the Echoing and Errors
in the gnu make manual for details
Related
This question already has answers here:
How do you get the list of targets in a makefile?
(27 answers)
Closed 1 year ago.
I am running compgen -c make in BASH on mac and am getting the following return values:
makepqg
makepqg
makepqg
make
makeinfo
makepqg
makepqg
But what I want and should? be getting (and do get when completing) is:
foo
bar
biz
baz
Which represent my various PHONY make rules that do automatic things.
How does one generate this list from the SHELL, generally, with the executable tool compgen?
(this is the ideal question because, from python3, subprocess is not able to simulate the interaction, and I'll have to do something more involved)
This is different than the duplicate candidate, "How do I get the targets in make (paraphrased)" in that I don't think the (non-working) command is a good answer, and this question is about compgen and make rather than make and the inner workings of make:
make -p no_targets__
| awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {split(\$$1,A,/ /);for(i in A)print A[i]}' "
| grep -v '__\$$' "
| sort
But can I get to some kind of a solution for my high level purpose using regexes?
In my opinion, no, because compgen is easy and memorable, whereas this kludge is hard and introduces drag on any code I'd pile on top.
Also, the duplicate allows for changes to be made to the makefile.
In my case, the make file must be considered a given, or what I am doing will be less useful.
So, more specifically, given any makefile, is there a solution involving tools outside of make that can look into make and get make to output a list of its recipes as it would for bash completion.
In other words: can this be done for ANY makefile (without loss of generality) without requiring write permissions on the makefile, and without simulating the tab-tab using a tty simulator?
Just a gist of it.
_make_phony() {
COMPREPLY=( )
# a lot of code
COMPREPLY=( foo bar biz baz )
}
complete -F _make_phony make
Now when you type make TabTab you'll get:
foo
bar
biz
baz
Of course you'll have to parse the Makefile to extract the real PHONY, and also handle each possible option of make, like make -f Makefile.osx and others; it can really become complex.
This question already has answers here:
Passing additional variables from command line to make
(8 answers)
Closed 3 years ago.
Have a makefile in which rule dev-create-empty-migration, currently, this rule has hardcoded argument accounts_table, this argument should not be hardcoded but should be passed as an argument at the time of rule invocation. e. g. make dev-create-empty-migration accounts_table.
Any ideas how to do that?
.PHONY: dev-create-empty-migration
dev-create-empty-migration:
migrate create -ext sql -dir
./pkg/acc/repo/postgres/migrations accounts_table
You should use a variable and store something in it. By using ?=, make first searches for an argument. If found, it uses the argument, otherwise the default content.
$ cat Makefile
VAR ?= derp
test:
#echo $(VAR)
$ make
derp
$ make VAR=lala
lala
Just because it's fun, you can also do something as follows. This omits the use of additional arguments, but you could of course make some hybrid.
$ cat Makefile
VAR := None
dev-create-empty-migration-%_table:
$(eval VAR=$(patsubst dev-create-empty-migration-%,%,$#))
#echo $(VAR)
$ make dev-create-empty-migration-derp_table
derp_table
This question already has answers here:
Prioritizing pattern rules in Make
(2 answers)
Closed 2 years ago.
The situation below is simplified heavily, but it does reflect the problem I'm having.
I have a Makefile that looks like this:
prefix-%.zip: prefix-%
zip -r $# $<
prefix-%: base
cp -r base $#
This is placed in a directory together with another directory base containing some files. If I execute the command
make prefix-1.zip
I would like the directory prefix-1 to be created using the second rule, and then the zip file prefix-1.zip to be created based on that directory using the first rule.
However, it seems like it finds the first rule with the stem '1', but it doesn't pick that rule, because the directory doesn't exist. It then seems to favour the second rule with the stem '1.zip'. Although this is a longer stem, that rule gets picked. I assume that this is due to the missing prerequisite for the first rule. Is there some way I can guide Make to the right rule, without manually first making the directory?
Btw, first making the directory and then the zip file works
make prefix-1
make prefix-1.zip
This is a kludge, but it works:
prefix-%.zip: prefix-%
zip -r $# $<
prefix-%: base | dummy%
cp -r base $#
dummy%:
#:
According to the manual, "a rule whose prerequisites actually exist or are mentioned always takes priority over a rule with prerequisites that must be made by chaining other implicit rules." So we make the second rule less attractive by giving it a dummy prerequisite that must be chained. Crude but effective. And we use the pipe (|) to make it an "order-only" prerequisite, so as not to force the directory to be rebuilt needlessly.
Here is my solution.
prefix-%.zip: base
cp -r base $(subst .zip,,$#)
zip -r $# $(subst .zip,,$#)
I use the subst function to strip out the .zip extension by replacing .zip with the empty string.
Question 1
If you define step
22 clean:
23 rm $(OBJECTS)
If there any way to gracefully "do nothing, if there is nothing to delete"?
Question 2
Assume the following line, again, is there a way to gracefully exit with a warhing when no files are found when processing line
6 SOURCES = $(shell echo src/*.cpp)
Question 3
How can one perform the final post processing on the final product, like mv $(PRODUCT) someDir? Where would this instruction be?
1) Just use rm -f, which is telling rm to ignore it if the files are missing.
3) That can just be the last step of the target that actually builds the product, or you can create a target named install (for example) that depends on your build target, and then contains this mv command.
Answering question #2:
SOURCES := $(or $(wildcard src/*.cpp), $(warning No source found in 'src'))
This will emit a warning when there are no files matching src/*.cpp pattern. SOURCES variable remains empty.
See the corresponding chapter in GNU Make manual.
This question already has answers here:
GNU Makefile rule generating a few targets from a single source file
(9 answers)
Closed 1 year ago.
How do I write a rule to generate set of files using a single action.
Example:
Files x, y, z are generated as a result of single execution of script t.sh which takes file a as input.
x y z: a
t.sh $#
GNU make tries to execute t.sh 3 times.
You could implement one of the solutions specified in the automake manual.
Because you've tagged this gnumake, I should also point out that using a GNU make pattern rule (the ones with %) with multiple targets WILL consider both generated from one execution of the rule: see the GNU make manual.