6 ms·
The real insanity with make is that it has no interface to check whether a Makefile contains a given target. Best you can do is to run make -n target to probe,
by joeyh 12y ago
The real insanity with make is that it has no interface to check whether a Makefile contains a given target.
Best you can do is to run make -n target to probe, but it's possible to write Makefiles that run code even though -n is used, which will defeat such probes at distribution scale. It quickly becomes an exercise in heuristics and output parsing.
- chaosfactor 12y agoWrite a target that greps the Makefile itself and extracts the targets.
- caust1c 12y agoThen write a parser to regenerate all the targets! It's a good thing make is turing complete. :-)
- TheDong 12y agoAs shown in the post, targets are not always grep-able. The post's makefile contained the target "par-30" even though that string appears nowhere on the page or in the makefile. You need to write a full parser to discover all the targets.
- Hello71 12y ago$ make -pqrf <(curl https://gist.githubusercontent.com/jgrahamc/2cc6df7fd5cd61c4d93f/raw/parallel) | grep '^[^ ]*:' | cut -d : -f 1 par-% par-22 par-30 par-5 par-27 par-31 all FORCE /proc/self/fd/13 par-13 par-9 par-23 par-19 .SUFFIXES par-15 par-7 parallel par-29 par-28 .parallel par-4 par-25 par-6 par-14 .DEFAULT par-24 par-0 par par-1 par-10 par-16 par-2 par-11 par-17 par-20 par-8 par-21 par-12 par-26 par-18 par-3
- TheDong 12y agoRight, you used 'make' as the parser. He said "grep the makefile". You're not grepping the makefile. Nice solution though!
- Hello71 12y ago> You need to write a full parser to discover all the targets. I don't think grep '^[^ ]*:' really counts as writing a parser.
- TheDong 12y agoRunning "make -p" is running a full parser which someone else wrote. Grep is not extracting the targets from a makefile there, it's extracting the targets from an intermediate representation of a makefile.
- Hello71 12y ago> The real insanity with make is that it has no interface to check whether a Makefile contains a given target. > > Best you can do is to run make -n target to probe, but it's possible to write Makefiles that run code even though -n is used, which will defeat such probes at distribution scale. It quickly becomes an exercise in heuristics and output parsing.
- TheDong 12y agoWe're arguing different things. The comment I replied to, chaosfactors, specifically specified grepping the makefile. You're arguing that you can find all the targets and I never said you can't. I simply said you can't find them all by only grepping the makefile.
- oso2k 12y agoI usually add two targets for my my projects: 'help' and 'showconfig'. 'make help' explains which targets to use and/or how to combine them. 'make showconfig' shows all the important what the important internal vars and common vars (CFLAGS, LDFLAGS, etc) are and their values.
- drothlis 12y agoThe "bash-completion" tab completion scripts for "make" do just that (run "make -npq") so presumably it's an acceptable thing to do for interactive use, that works reasonably well for some (most?) makefiles. "At distribution scale"... judging by your username, I take it your use case is something like finding out if a source tarball provides the standard targets like "install" and "distcheck", for all packages in debian? I can see how that would be rather painful. I wonder if there's room for adding a "--dry-run-yes-really-dont-run-any-recipes-at-all" flag to make. As far as I remember the main use case for the current behaviour is (a) to run recipes that create makefiles that are then included into the main makefile, used in build systems that automatically figure out header dependencies and things like that; and (b) process makefiles in subdirectories for "recursive make" build systems. I wonder if you don't do those steps, would you actually miss out on any significant information re. top-level targets? I imagine that use case (a) is used to add prerequisites to existing targets, rather than creating new targets. Or maybe a more general solution, instead of "--dry-run-yes-really", would be providing access to make's parser as a library, instead of having to parse the output of "make -p". I'm sure IDEs could make good use of that. Who's got time to implement that though.