Como posso parcialmente serializar com o GNU make

4

Quando tenho uma tarefa de fabricação em que um destino específico precisa ser feito antes de outra, enquanto no modo paralelo, isso é simples ao usar o SunPro Make (dmake). O makefile a seguir:

install:  dir dir/file

dir:
    mkdir dir

dir/file:
    cp source dir/file

pode ser feito paralelamente para se tornar seguro alterando a primeira linha para:

install: dir .WAIT dir/file

ou usando:

.NO_PARALLEL: install

O restante do makefile ainda será tratado no modo paralelo e até mesmo uma lista se os destinos à esquerda ou à direita de .WAIT forem tratados no modo paralelo.

Consulte: link e link

mas o GNU make não parece ter uma opção semelhante. Existe realmente nenhuma maneira de fazer isso com o GNU make?

Para ser mais específico, a solução precisa ser escrita de forma que permita que o makefile seja processado com outras implementações de make.

O alvo especial .WAIT poderia, e. estar em uma macro dependente do programa make que é chamado, e. $ (ESPERE)

Observe que há uma solução aparente que não ajuda:

Em teoria, pode-se tornar dir uma dependência de dir/file para impor a criação de dir antes de tentar copiar para dir/file, , mas se posteriormente você copiar outro arquivo para dir, , isso tornará dir mais recente que dir/file . Como resultado, chamar make mais de uma vez copiava para dir/file de novo e de novo, sem o resultado esperado de make para fazer a cópia apenas no caso de a origem se tornar mais recente que dir/file.

Isso levanta a questão alternativa se pode haver uma topologia de dependências que imponha make para criar dir antes de copiar para dir/file sem tornar dir uma dependência de dir/file.

    
por schily 02.05.2018 / 22:21

3 respostas

1

Esta é a minha própria resposta, derivada da ideia apresentada por Filipe Brandenburger e dos métodos genéricos utilizados no sistema Schily Makefile:

O sistema makefile garante que os seguintes make macros estejam configurados desta maneira:

WAIT=       # empty with GNU make
WAIT= .WAIT # .WAIT special target with SunPro Make

MAKEPROG= <name of the make program> # This is from: smake, gmake, sunpro

_UNIQ= .XxZzy-

Agora o makefile que faz uso das definições de macro acima:

_NORULE=    $(_UNIQ)$(MAKEPROG)
__NORULE=   $(_NORULE:$(_UNIQ)gmake=)
NORULE=     $(__NORULE:$(_UNIQ)%=%)

install: dir $(WAIT) dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

$(NORULE)dir/file: | dir

$(NORULE) se expande para nada com o gmake e para sunpro com o SunPro Make.

No caso do gmake, todo o makefile se expande para:

install: dir dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

dir/file: | dir

No caso do SunPro Make, todo o makefile se expande para:

install: dir .WAIT dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

sunprodir/file: | dir

A última linha é vista como uma regra de lixo eletrônico sem relevância.

    
por 03.05.2018 / 15:13
6

No GNU make, você pode usar pré-requisitos somente de pedido para garantir que dir seja criado antes que a regra para criar dir/file seja executada.

Consulte esta página para obter mais detalhes.

Você pode ver no exemplo no manual do GNU make que é realmente feito sob medida para adicionar dependência em um diretório sendo criado antes de criar arquivos sob ele.

No caso do seu exemplo específico, algo assim deve ser feito:

dir/file: | dir
        cp source dir/file

Embora você não precise modificar a regra existente, você pode simplesmente adicionar essa dependência em algum outro lugar no Makefile ...

To be more specific, the solution needs to be written in a way that allows the makefile to be processed with other make implementations.

Eu não acho que isso funcionaria em outras implementações de make ... Uma solução possível é criar um GNUmakefile que seria include o% realMakefile e também o GNU adicionam extensões específicas.

Você também pode fazer o GNU make ignorar uma regra como .WAIT definindo-a como uma regra falsa em seu GNUmakefile .

Espero que esses ponteiros sejam úteis!

    
por 03.05.2018 / 00:03
4

Você precisa adicionar dependências para que os diretórios sejam criados antes dos arquivos sob eles.

É possível usar um arquivo "marker" para a dependência no diretório, assim, criar um arquivo sob ele não afetará o registro de data e hora do diretório. Isso não requer nenhum GNU para fazer recursos específicos.

No seu exemplo:

install: dir/file

dir/.marker:
        mkdir -p dir
        touch dir/.marker

dir/file: dir/.marker
        cp source dir/file

Você pode usar algo como .directory ou .dir ou .folder para o arquivo do marcador ...

    
por 03.05.2018 / 01:41