tutorial how example español create c build makefile dry

how - ¿Cómo eliminar la duplicación en Makefile?



makefile structure (1)

Un buen primer comienzo sería dejar de repetir los objetivos / etc. en los cuerpos de reglas ellos mismos y en su lugar usan las variables automáticas para ellos. Así que ''$@'' para el nombre del archivo de destino, ''$(@D)'' para la ruta del directorio (como dirname ) del nombre del archivo de destino, etc.

Que te atrapa:

duo = ./node_modules/.bin/duo build: lib/background/build lib/page/build lib/popup/build lib/background/build: lib/background/build/build.js lib/background/build/build.css lib/page/build: lib/page/build/build.js lib/page/build/build.css lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css lib/background/build/build.js: lib/background/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) lib/background/index.js > ''$@'' lib/page/build/build.js: lib/page/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) lib/page/index.js > ''$@'' lib/popup/build/build.js: lib/popup/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) lib/popup/index.js > ''$@'' lib/background/build/build.css: lib/background/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) lib/background/index.css | $(myth) > ''$@'' lib/page/build/build.css: lib/page/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) lib/page/index.css | $(myth) > ''$@'' lib/popup/build/build.css: lib/popup/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) lib/popup/index.css | $(myth) > ''$@''

Luego, al darse cuenta de que las reglas de patrones son útiles cuando tiene objetivos y prerrequisitos que comparten patrones de nombre de archivo y cuerpos de reglas similares, puede comenzar a usarlos también. También te dan una variable automática adicional.

Obtienes esta etapa (intermedia):

duo = ./node_modules/.bin/duo build: lib/background/build lib/page/build lib/popup/build lib/background/build: lib/background/build/build.js lib/background/build/build.css lib/page/build: lib/page/build/build.js lib/page/build/build.css lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css %/build/build.js: %/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.js > ''$@'' %/build/build.js: %/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.js > ''$@'' %/build/build.js: %/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.js > ''$@'' %/build/build.css: %/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.css | $(myth) > ''$@'' %/build/build.css: %/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.css | $(myth) > ''$@'' %/build/build.css: %/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.css | $(myth) > ''$@''

Y les ves que realmente acabas de obtener dos reglas duplicadas para que las combines.

duo = ./node_modules/.bin/duo build: lib/background/build lib/page/build lib/popup/build lib/background/build: lib/background/build/build.js lib/background/build/build.css lib/page/build: lib/page/build/build.js lib/page/build/build.css lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css %/build/build.js: %/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.js > ''$@'' %/build/build.css: %/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.css | $(myth) > ''$@''

Y luego, dado que make no maneja los objetivos / prerrequisitos del directorio tan bien como a uno le gustaría, puede descartar los objetivos intermedios lib/background/build , lib/page/build , y lib/popup/build y solo listar los archivos reales como prereqs para la build .

duo = ./node_modules/.bin/duo build: lib/background/build/build.js lib/background/build/build.css / lib/page/build/build.js lib/page/build/build.css / lib/popup/build/build.js lib/popup/build/build.css %/build/build.js: %/index.js node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.js > ''$@'' %/build/build.css: %/index.css node_modules component.json @mkdir -p ''$(@D)'' @$(duo) ''$*''/index.css | $(myth) > ''$@''

Probablemente debería mencionar que no probé esto (por falta de deseo de simular el diseño del directorio / etc.), Pero las transformaciones fueron sencillas y los conceptos son bastante simples, por lo que debería funcionar bien. Pero todo es posible.

Para limpiar los requisitos previos de build podrías usar algo como:

build: $(foreach d,background page popup,$(addprefix lib/$d/build/,build.js build.css))

¿Hay alguna manera de simplificar este tipo de repetición en un Makefile?

duo = ./node_modules/.bin/duo build: lib/background/build lib/page/build lib/popup/build lib/background/build: lib/background/build/build.js lib/background/build/build.css lib/page/build: lib/page/build/build.js lib/page/build/build.css lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css lib/background/build/build.js: lib/background/index.js node_modules component.json @mkdir -p lib/background/build @$(duo) lib/background/index.js > lib/background/build/build.js lib/page/build/build.js: lib/page/index.js node_modules component.json @mkdir -p lib/page/build @$(duo) lib/page/index.js > lib/page/build/build.js lib/popup/build/build.js: lib/popup/index.js node_modules component.json @mkdir -p lib/popup/build @$(duo) lib/popup/index.js > lib/popup/build/build.js lib/background/build/build.css: lib/background/index.css node_modules component.json @mkdir -p lib/background/build @$(duo) lib/background/index.css | $(myth) > lib/background/build/build.css lib/page/build/build.css: lib/page/index.css node_modules component.json @mkdir -p lib/page/build @$(duo) lib/page/index.css | $(myth) > lib/page/build/build.css lib/popup/build/build.css: lib/popup/index.css node_modules component.json @mkdir -p lib/popup/build @$(duo) lib/popup/index.css | $(myth) > lib/popup/build/build.css

Básicamente, quiero ejecutar un comando de make build simple desde el nivel superior, y solo reconstruye estos subproyectos si es necesario. Me gustaría no tener que usar un Makefile para cada subproyecto porque también es repetitivo. Todo lo que he intentado en relación con las rutas de comodines no ha funcionado, por lo que me pregunto si existe alguna forma de hacerlo. Por ejemplo, intenté hacer algo como esto (similar para js y css) pero no tuve suerte:

js = $(shell find lib test -type f -name ''*.js'' ! -path "*build.js") $(js)/build/build.js: node_modules component.json # somehow get the directory such as lib/background based on the make command? local dir=$(shell dirname $(shell dirname $@)) @mkdir -p $(dir)/build @$(duo) $(dir)/index.js > $(dir)/build/build.js

¿Alguna idea de cómo hacer esto SECO?