Preventing two instance instances from fulfilling the same goal (parallel make)

I am trying to do parallel work on our build server. I encounter very frequent problems here, when two examples of attempts to make two different goals, for example A and B, almost simultaneously try to make the goal that is required by both, say C.

Because both instances try to group C into different instances, C fails for either of them, because creating C requires some files to be moved here and there, and one of these instances finishes moving or deleting the already created file.

Is there a general construct that I can use to prevent re-entering the makefile if the target is already created?

Update:

Ok, let me say this: My application requires the presence of A.lo and B.lo. These A.lo and B.lo are libraries that are also associated with C.lo. So the rules look like

app.d: A.lo B.lo (other lo s)

(do linking)

In some other directory they say A (which A.lo will be in):

A.lo: C.lo (other .os and .lo s)

(do linking)

In some other directory, say B (which B.lo will host):

B.lo: C.lo (other .os and .lo s)

(do linking)

Thus, when creating app.d, forks with two parallel records are created for the purposes of A.lo and B.lo. When directories A and B are entered, the other two threads are dropped for the target C.lo independently of each other, and sometimes both of them bind C.lo at the same time, which leads to the failure of one of them with some strange errors, such as file not recognized (as it may be written by another instance of the linker)

How do I solve this? It is not possible to create A.lo and B.lo without C.lo associated with them.

+4
source share
2 answers

This may seem a bit, well, obviously, but the simplest solution is to arrange C to explicitly create before A or B That way, when the recursive command starts A and B , C will already be updated, and no one will try to build it.

If your makefile makefile looks like this:

 all: buildA buildB buildA: $(MAKE) -CA buildB: $(MAKE) -CB 

You can expand it as follows:

 all: buildA buildB buildA: buildC $(MAKE) -CA buildB: buildC $(MAKE) -CB buildC: $(MAKE) -CC 

You didn’t provide a lot of details about your particular assembly, so it’s probably not just stuffing and working, but I hope you get this idea.

+2
source

I solve this problem using the mkdir technique:

 SHELL = /bin/bash all: targetC targetD targetC: targetA ............ targetD: targetB ............ targetA targetB: source -mkdir source.lock && ( $(command) < source ; rm -r source.lock ) $(SHELL) -c "while [ -d source.lock ] ; do sleep 0.1 ; done" 

I would be happy to see a more elegant solution.

+1
source

Source: https://habr.com/ru/post/1343740/


All Articles