Is there a way to verify that given targets are marked .PHONY in makefile? - gnu-make

I am having a bunch of make files in different projects that I want to verify against some criteria of all targets or a list of targets are marked .PHONY.
I am not sure whether such a test already exists or if it is possible to introduce one?

As far as I'm aware, no.
make / gmake itself has no functionality to print that.
However, it's easy to find out yourself from make's dependency/target database output:
make -nsp --no-print-directory --always-make
||| | |
||| | run, no matter whether
||| | parts have already been built
||| |
||| don't print the directory structure
|||
||\--- print the database
|\---- be silent, otherwise
\----- don't actually build anything
prints what make figured out are all targets.
make -nsp --no-print-directory --always-make | grep -E '^\.PHONY:'
prints all the targets that are dependencies of the .PHONY "pseudo"-target.
You can then do with that list whatever you want :)

Related

Arcanist automatically populate reviewers line based on arc cover

If you run arc cover it will show you who last edited the lines you have changed, which is good for deciding who should be reviewers.
Is there a way to have Arcanist automatically do this and then pre-populate the Reviewers: line in the commit message with those people?
You can get a delimited list of reviewers with this one liner:
arc cover | grep '^[^ ]' | paste -s -d, -
And you can specify reviewers when creating a diff, using the --reviewers option.
Therefore you should be able to do something like this:
arc diff --reviewers "$(arc cover | grep '^[^ ]' | paste -s -d, -)"
But this only works if you use Phabricator usernames as git author names.

Complex command execution in Makefile

I have a query regarding the execution of a complex command in the makefile of the current system.
I am currently using shell command in the makefile to execute the command. However my command fails as it is a combination of a many commands and execution collects a huge amount of data. The makefile content is something like this:
variable=$(shell ls -lart | grep name | cut -d/ -f2- )
However the make execution fails with execvp failure, since the file listing is huge and I need to parse all of them.
Please suggest me any ways to overcome this issue. Basically I would like to execute a complex command and assign that output to a makefile variable which I want to use later in the program.
(This may take a few iterations.)
This looks like a limitation of the architecture, not a Make limitation. There are several ways to address it, but you must show us how you use variable, otherwise even if you succeed in constructing it, you might not be able to use it as you intend. Please show us the exact operations you intend to perform on variable.
For now I suggest you do a couple of experiments and tell us the results. First, try the assignment with a short list of files (e.g. three) to verify that the assignment does what you intend. Second, in the directory with many files, try:
variable=$(shell ls -lart | grep name)
to see whether the problem is in grep or cut.
Rather than store the list of files in a variable you can easily use shell functionality to get the same result. It's a bit odd that you're flattening a recursive ls to only get the leaves, and then running mkdir -p which is really only useful if the parent directory doesn't exist, but if you know which depths you want to (for example the current directory and all subdirectories one level down) you can do something like this:
directories:
for path in ./*name* ./*/*name*; do \
mkdir "/some/path/$(basename "$path")" || exit 1; \
done
or even
find . -name '*name*' -exec mkdir "/some/path/$(basename {})" \;

GNU Make global variables updated in sub-makes

I need some help with my Makefile for a project. The source directory looks something like this.
|-- Makefile
|-- drivers
| |-- Makefile
| |-- tty
| |-- Makefile
| |-- console.c
| |-- keyboard.c
|-- kernel
| |-- Makefile
| |-- kmain.c
In the top Makefile, I have exported a variable OBJECTS that I want to populate with object files so I can build and link them together in the top Makefile.
I want to update OBJECTS in, say, drivers/tty/Makefile by doing something like this:
OBJECTS += $(CURDIR)console.o
OBJECTS += $(CURDIR)keyboard.o
But the change to OBJECTS does not bubble up to the top Makefile. I've been looking at the Makefiles in the Linux source tree, and they seem to be doing something similar. However, I can't get it to work. Am I missing something here?
You appear to be using Make recursively, something like
# Makefile:
export OBJECTS :=
all:
$(MAKE) -C drivers/tty
#echo OBJECTS is $(OBJECTS)
# drivers/tty/Makefile:
OBJECTS += $(CURDIR)console.o
all:
whatever
This doesn't work, because each Make has its own OBJECTS; the child Make can't modify variables in the parent Make. It's export, not import/export or share (there's no such thing as import/export or share, I'm just trying to illustrate).
You can get the effect you want by including the other makefiles instead of invoking them:
# Makefile:
OBJECTS :=
all: DRIVERS_TTY
#echo OBJECTS is $(OBJECTS)
include drivers/tty/Makefile
# drivers/tty/Makefile:
OBJECTS += drivers/tty/console.o
DRIVERS_TTY:
whatever
You'll notice there is some unpleasant location-dependency there; drivers/tty/Makefile has "drivers/tty" spelled out inside it, which makes maintenance a pain. There are ways to fix that, once you have this basic include trick working.
When you recursively run make it opens a new subshell for each subsequent call to make so you can't go back up the chain with your exports. One method would be for each call to a submake to append to an object list file and then possibly include that file. A better solution is to probably do something along the lines of having your main makefile include each of these submake files directly instead of calling make on them. This method allows the OBJECTS variable to be built up using the each of the submake files with your OBJECTS += statements. Another added benefit is that you are running just one instance of make instead of multiple submakes which allows make to do better dependency generation. Take a look at "Recursive make considered harmful" http://aegis.sourceforge.net/auug97.pdf
One cool makefile build system that was posted up here before by user Dan Moulding https://stackoverflow.com/users/95706/dan-moulding really showed off a lot of the cool stuff you can do with submake files all while having just one master makefile. Dan's boilermake project is here: https://github.com/dmoulding/boilermake

What would this command do if run in UNIX?

I saw this command posted somewhere, :(){ :|:& };:
What would it do if I ran it in UNIX, I don't feel like trying myself in case it does something bad
This is a fork bomb and it is very bad.
It will spawn many many processes, the number growing exponentially as each process spawns two more. They will clog your system until it falls over.
Don't run it. Its fork bomb. it will bring down your system.
From wikipedia :
/- Define the function ':' without any parameters '()' as follows:
| /- Beginning of function-block.
| | /- Load a copy of the function ':' into memory ...
| | |/- ... and pipe its output to ...
| | ||/- ... another copy of the ':'-function, which has to be loaded into memory.
| | ||| (In other words, ':|:' loads two more copies of ':', thus causing a chain-reaction)
| | |||/- Disown the functions (make them a background process), so that the children of a parent
| | |||| will not be killed when the parent gets auto-killed.
| | |||| /- End of function-block.
| | |||| |/- End of definition.
/-\| |||| ||/- Execute the function ':'. The chain-reaction begins.
:(){ :|:& };:
Here is the link http://en.wikipedia.org/wiki/Fork_bomb

How should I collect dependencies from Adobe Flex files?

I'm looking for a way to collect the file dependencies from Flex ActionScript and MXML files. I was hoping that mxmlc could spit them out (like gcc's -M option), but its option list doesn't seem to have anything relevant. I could write a parser, but would prefer not to reinvent the wheel if it has already been done, particularly given the two very different languages involved. In particular, star imports and in-package implicit imports could be troublesome.
Is there a program available to do this for me?
i am suspecting that since mxmlc is pretty smart and handles dependencies correctly, few people would need to figure out the dependencies themselves, and so the tool may have not come into existence.
I guess parsing the import statements would be the way to go?
The -link-report option of mxmlc produces a file containing most of the appropriate information, except that it reports fake file names for embedded assets, and ignores included source files. To collect everything, I now have the following in my makefile:
.deps/%.d: .deps/%.xml
# $#: $<
grep '<script name=./' $< | cut -f2 -d'"' | cut -f1 -d'(' | cut -f1 -d'$$' | sort -u | sed -e "s|^$$(pwd)/||" > .deps/$*.f
grep '\.mxml$$' .deps/$*.f | xargs grep -H 'mx:Script source' | sed -s 's|/[^/]*.mxml:.*source="\([^"]*\)".*|/\1|;' > .deps/$*.i
for path in $$(grep -h '\.\(mxml\|as\|css\)$$' .deps/$*.[fi] | xargs grep '\bEmbed([^.)]' | \
sed "s#\\(\\w\\+\\)/.*Embed([^'\")]*['\"][./]*\\([^'\"]*\\)['\"] *[,)].*#\\1/*/\\2#"); \
do find */src -path "$$path"; done | sort -u > .deps/$*.e
cat .deps/$*.[fie] | sed -e "s|^|$(flashpath)$*.swf $# : |" > $#
# This includes targets, so should not be before the first target defined here.
built := $(wildcard .deps/*.xml)
include $(built:xml=d)
All of the mxmlc and compc commands in the makefile now have -link-report generating an appropriately-named .xml file in the .deps directory. I still have to search files for Embed and Script directives, but the hard part (determining which classes get included) has been done for me. I could use a real parser for each step, but grep, sed, and cut work well enough for the files as given.

Resources