wiele celów z jednej receptury i równoległe wykonanie

Mam projekt, który zawiera generator kodu, który generuje kilka plików .c i .h z jednego pliku wejściowego z jednym wywołaniem generatora kodu. Mam regułę, która ma pliki .c i .h jako wiele celów, plik wejściowy jako warunek wstępny, a receptura jest wywołaniem generatora kodu. Następnie mam kolejne reguły do ​​kompilowania i łączenia wygenerowanych plików .c.

Działa to dobrze z współczynnikiem -j równym 1, ale jeśli zwiększę współczynnik j, znajdę wiele wywołań generatora kodu, aż do współczynnika -j lub liczby oczekiwanych plików docelowych, w zależności od tego, która wartość jest najmniejsza. Jest to złe, ponieważ wielokrotne wywołania generatora kodu mogą powodować awarie, ponieważ wygenerowany kod jest wielokrotnie zapisywany.

Nie opublikuję tutaj mojego rzeczywistego (dużego) kodu, ale udało mi się skonstruować mały przykład, który wydaje się wykazywać to samo zachowanie.

Plik Makefile wygląda tak:

output.concat: output5 output4 output3 output2 output1
    cat $^ > $@

output1 output2 output3 output4 output5: input
    ./frob input

clean:
    rm -rf output*

Zamiast generatora kodu, w tym przykładzie napisałem prosty skrypt powłoki,frob który generuje wiele plików wyjściowych z jednego pliku wejściowego:

#!/bin/bash

for i in {1..5}; do
    {
    echo "This is output${i}, generated from ${1}. input was:"
    cat ${1}
    } > output${i}
done

Kiedy uruchamiam ten Makefile z czynnikami -j nie-jedności, otrzymuję następujące dane wyjściowe:

$ make -j2 
./frob input
./frob input
cat output5 output4 output3 output2 output1 > output.concat
$

Widzimy./frob tutaj zostanie wywołany dwukrotnie, co jest złe. Czy jest jakiś sposób, w jaki mogę skonstruować tę regułę w taki sposób, że receptura zostanie wywołana tylko raz, nawet z czynnikiem nie-jedności?

Zastanawiałem się nad zmianą reguły, tak że celem jest tylko jeden z oczekiwanych plików wyjściowych, a następnie dodanie innej reguły bez receptury, tak aby jej cele były pozostałymi oczekiwanymi plikami wyjściowymi, a wymaganie wstępne jest pierwszym oczekiwanym plikiem wyjściowym. Ale nie jestem pewien, czy to zadziała, ponieważ nie wiem, czy mogę zagwarantować kolejność generowania plików, a tym samym skończyć się zależnościami kołowymi.

questionAnswers(4)

yourAnswerToTheQuestion