How can I prevent race conditions in make? - concurrency

As the title suggests, how can I prevent race conditions in make?
My specific use case is where I want clean and then build the all target:
make -j 4 clean all
Should I give up and settle for make clean && make -j 4 all?

You cannot really execute in parallel a recipe that builds a target and another one that destroys it.
What a use case do you have in mind that would not be satisfied with:
make clean && make -j4
?

I think the only way to make this work is to put this in the Makefile:
all : clean
which you don't want (obviously). My next idea would be:
clean_all: clean
$(MAKE) all
That would allow you to write make -j clean_all but I'm not happy with it, either.

Related

Issue with Makefile

I have to submit a makefile for a project and I can't get it to work. I am trying to use the appropriate c++ 11 standard, execute project2,out, and run the cpp files in my src, but I keep getting the error "Nothing to be done for 'Makefile'."
#specify std=c++11 in your makefile
CXXFLAGS += -std=c++11
#Your executable should be named project2.out
main: g++ -o project2.out src/*.cpp
clean: del *.o
When asking questions please always cut and paste the exact command you typed and the exact output you got, properly formatted for SO (if you get a lot of output trim it down to the relevant parts which includes the command make invoked and at least the first few (not last!!) errors you get).
In this case, if you'd shown us what command you were running I'll bet it's this:
make Makefile
that's wrong. The arguments to make are not the makefile to use: they're the target you want to update. Here you've asked make to update your Makefile, but it already exists so make says "nothing to do".
Just run:
make
to build the default target, or make clean to build the clean target.
Once you get past this, you can begin to work on why your makefile may or may not work.

GNU recursive make - how to capture make variables to execute nested makefile

I have a bunch of qmake-generated makefiles each of which call make inside them (recursive make) in a chained manner.
After my build is over, the qmake-generated makefiles are all on disk so you'd think I could just call make on one of them if I wanted to 'replay' one particular makefile. Wrong.
When I try make-ing one, it fails, probably because there's a bunch of (environment) variables that it normally inherits from the calling makefile during the normal build.
Except for the variables, each qmake-generated makefile is pretty self-contained.
QUESTION
How can I simulate the 'normal' environment for a given recursive make so that I can call it in isolation?
I'm thinking I'd have to do something with the --print-data-base output: parse it and then call make with the same vars and values it had during the normal build.
WHY
I'm doing this because I need to modify the compile commands for ONE makefile but it's all controlled by the top-level .conf and I'm getting in way too deep.
I assume the problem is that you need to find this information before you get a chance to make any changes to the generated makefiles. Therefore, this solution is focused on shell commands (I'm assuming you're on Linux, since you don't say).
After starting your build, the first time, use something like:
ps -ef | head -1
ps -ef | grep make
to find make processes involved in the build. The PID column lists the Process ID of the make process, while the PPID column lists that of its parent. Use this information to find the top-level make process. Then, run:
strings /proc/<pid>/environ | sort > /tmp/make_env
env | sort > /tmp/normal_env
diff /tmp/normal_env /tmp/make_env
This will show you how the make process' environment differs from that of your current shell.
Now, that might not solve your problem, because GNU Make allows variables to be specified as commandline parameters. So, you should also check how it's being run:
strings /proc/<pid>/cmdline
That will print each commandline argument of <pid>, on a separate line.
BTW, when variables are passed to GNU Make via commandline arguments, they're handled by overriding any instance of the same variable, that might be contained within the makefile.
Within a makefile, you can see its environment using:
$(info My environment is $(shell env))
You can see its commandline options using:
$(info MAKEFLAGS = $(MAKEFLAGS))
If you only want to see the overrides, use MAKEOVERRIDES:
$(info MAKEOVERRIDES = $(MAKEOVERRIDES))
Finally, the targets can be seen using:
$(info MAKECMDGOALS = $(MAKECMDGOALS))

Compiling Netcat with DFLAGS

I've been trying to compile netcat so that I can use the -e option but I am not sure as to how or where to place the custom flags.
So far I've done:
./configure
Make
and then I edit the Makefile with:
DFLAGS = -DGAPING_SECURITY_HOLE -DTELNET
and then do make install.
Is that the correct way to do this?
You don't really say what you are trying to do, but normally you want CFLAGS not DFLAGS, and you want something like ./configure 'CFLAGS=blah', then make. You may have to play around with quoting depending on your shell. You may also find there is an option to configure to do this for you, normally starting with --with.

How do I define a dependency graph with unknown intermediate node names?

I'm using a tool chain where I do not know the names of all of the intermediate files.
E.g. I know that I start out with a foo.s, and go through several steps to get a foo.XXXX.sym and a foo.XXXX.hex, buried way down deep. And then running other tools on foo.XXXX.hex and foo.XXXX.sym, I eventually end up with something like final.results.
But, the trouble is that I don't know what the XXXX is. It is derived from some other parameters, but may be significantly transformed away from them.
Now, after running the tool/steps that generate foo.XXXX.{sym,hex}, I now typically scan the overall result directory looking for foo.*.{sym,hex}. I.e. I have code that can recognize the intermediate outputs, I just don't know exactly what the names will be.
I typically use make or scons - actually, I prefer scons, but my team highly prefers make. I'm open to other build tools.
What I want to do is be able to say (1) "make final.results", or "scons final.results", (2) and have it scan over the partial tree; (3) figure out that, while it does not know the full path, it definitely knows that it has to run the first step, (4) after that first step, look for and find the foo.XXX.* files; (5) and plug those into the dependency tree.
I.e. I want to finish building the dependency tree after the build has already started.
A friend got frustrated enough with scons' limitations in this area that he wrote his own build tool. Unfortunately it is proprietary.
I guess that I can create a first build graph, say in make with many .PHONY targets, and then after I get through the first step, generate a new makefile with the new names, and have the first make invoke the newly generated second makefile. Seems clumsy. Is there any more elegant way?
GNU make has an "auto-rexec" feature that you might be able to make use of. See How Makefiles Are Remade
After make finishes reading all the makefiles (both the ones found automatically and/or on the command line, as well as all included makefiles), it will try to rebuild all its makefiles (using the rules it knows about). If any of those makefiles are automatically rebuilt, then make will re-exec itself so it can re-read the newest versions of the makefiles/included files, and starts over (including re-trying to build all the makefiles).
It seems to me that you should be able to do something with this. You can write in your main makefile and "-include foo.sym.mk" for example, and then have a rule that builds "foo.sym.mk" by invoking the tool on foo.s, then running your "recognized the next step" code and generate a "foo.sym.mk" file which defines a rule for the intermediate output that got created. Something like (due to lack of specificity in your question I can't give true examples you understand):
SRCS = foo.s bar.s baz.s
-include $(patsubst %.s,%.sym.mk,$(SRCS))
%.sym.mk: %.s
<compile> '$<'
<recognize output and generate makefile> > '$#'
Now when make runs it will see that foo.sym.mk is out of date (if it is) using normal algorithms and it will rebuild foo.sym.mk, which as a "side effect" causes the foo.s file to be compiled.
And of course, the "foo.sym.mk" file can include ANOTHER file, which can recognize the next step, if necessary.
I'm not saying this will be trivial but it seems do-able based on your description.
Make constructs the graph before running any rule, so there won't be a perfect answer. Here are some reasonably clean solutions.
1) use PHONY intermediates and wildcards in the commands. (You can't use Make wildcards because make expands them before running rules.)
final.results: middle
# build $# using $(shell ls foo.*.sym) and $(shell ls foo.*.hex)
.PHONY: middle
middle: foo.s
# build foo.XXXX.sym and foo.XXXX.hex from $<
2) Use recursive Make (which is not as bad as people say, and sometimes very useful.)
SYM = $(wildcard foo.*.sym)
HEX = $(wildcard foo.*.hex)
# Note that this is is the one you should "Make".
# I've put it first so it'll be the default.
.PHONY: first-step
first-step: foo.s
# build foo.XXXX.sym and foo.XXXX.hex from $<
#$(MAKE) -s final.results
final.results:
# build $# using $(SYM) and $(HEX)
3) Similar to 2, but have a rule for the makefile which will cause Make to run a second time.
SYM = $(wildcard foo.*.sym)
HEX = $(wildcard foo.*.hex)
final.results:
# build $# using $(SYM) and $(HEX)
Makefile: foo.s
# build foo.XXXX.sym and foo.XXXX.hex from $<
#touch $#

Autoconf/Automake: How to avoid passing the "check" option to AC_CONFIG_SUBDIRS

I'm using Autoconf to build my c++ project. It uses third party code which is also built with the help of Autoconf/Automake. So in my configure.ac I've got the following line:
AC_CONFIG_SUBDIRS([subdirectoryname])
Everything works fine, but I also use the feature to let tests be automatically made if make check is executed - which is done by the third party code as well. Because these tests take a while it's annoying to execute them each time I want to test my own code. So is there any way to avoid that the check option is passed to the subdirectory's Makefile?
Update: Overriding check-recursive does not seem to be an option, as my top-level Makefile.am looks (more or less) like this:
SUBDIRS=library src
So disabling checking on this level would also disable the checking inside my src folder. And that's not what I want to achieve. I just want to disable the checking in the library directory.
Overriding check-recursive in your Makefile.am should work:
check-recursive:
#true
or, if you only wanted to check in a specific directory:
check-recursive:
$(MAKE) -C src check
according to the autoconf manual, it will execute a configure.gnu script in the subdirectory if it finds one. Theoretically that could be a script which adds a --disable-tests or similar option to a call to ./configure
That said, I've yet to get this to work on a project of my own. :-/