Pregunta Variables específicas de destino como requisitos previos en un archivo Makefile


Intento escribir un Makefile de GNU que tenga una carga de objetivos similares, donde los comandos de compilación varían ligeramente entre ellos. Estoy tratando de usar variables específicas del objetivo para representar estas variaciones Algunos de estos valores de variable hacen referencia a los archivos que quiero usar como requisitos previos. Por ejemplo:

target_1:special_filename=target1_prereq
target_2:special_filename=target2_prereq

target_1 target_2: common_filename $(special_filename)
    do_something common_filename --a-weird-option=$(special_filename)

Cuando llamo 'make target_1', quiero que haga target1_prereq si no existe. Por el momento, no parece usar target1_prereq como un requisito previo, aunque el comando de compilación (do_something) se invoque con el parámetro correcto.

Estoy usando GNU Make 3.80.


Editar: Algunas complicaciones más del sistema real. Algunas de las variables se basan en los valores de otras variables. La especificación manual de los requisitos previos no se escalaría. Un ejemplo un poco más complicado:

target_1:special_filename_base=target1_prereq
target_2:special_filename_base=target2_prereq

some_filename_a = $(special_filename_base).exta
some_filename_b = $(special_filename_base).extb

target_1 target_2: common_filename $(special_filename_b) $(special_filename_a)
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b)

14
2017-08-27 10:01


origen


Respuestas:


Una variable específica del objetivo se define solo en los comandos del objetivo (o en otras asignaciones específicas del objetivo); no se puede usar como uno de los requisitos del objetivo. No creo que haya una forma clara de hacer lo que quiera en Make, pero hay varios enfoques de poco valor, como los siguientes:

EXTENSIONES = .exta .extb
target_1: $ (addprefix target1_prereq, $ (EXTENSIONES))
target_2: $ (addprefix target2_prereq, $ (EXTENSIONES))

target_1 target_2: common_filename
    do_something nombre_archivo_común --a-opción-extraña = $ (filtro% .exta, $ ^) --segundo = $ (filtro% .extb, $ ^)

3
2017-08-31 18:08



Como una solución simple:

target_1: special_filename = target1_prereq
target_1: target1_prereq
target_2: special_filename = target2_prereq
target_2: target2_prereq

target_1 target_2: common_filename $ (special_filename)
    do_something nombre_archivo_común --a-strange-option = $ (special_filename)

Hay algo de redundancia, pero está localizado, así que no es tan malo.


2
2017-08-27 10:12



He encontrado una forma bastante limpia de dejar de lado esta limitación. Sería algo como esto:

target_1:export special_filename_base=target1_prereq
target_2:export special_filename_base=target2_prereq

some_filename_a = $(special_filename_base).exta
some_filename_b = $(special_filename_base).extb

target_1 target_2:
    $(MAKE) -f $(firstword $(MAKEFILE_LIST)) target-proxy

target-proxy: common_filename $(special_filename_b) $(special_filename_a)
    do_something common_filename --a-weird-option=$(special_filename_a) --second=$(special_filename_b)

Dos puntos importantes:

  1. export las variables de destino, para que estén accesibles cuando volvamos a ejecutar Makefile.
  2. Cree un destino de proxy que tenga todos los requisitos previos originales de target_1 target_2 y en target_1 target_2 invocar el Makefile de nuevo con este objetivo de proxy. Dado que las variables específicas del objetivo tendrán valores para entonces ( son en la receta en ese momento) y Ellos eran exported, estarán disponibles en target-proxy - voila :)

La desventaja de este enfoque es que estamos creando otro make proceso - si es solo otro, entonces probablemente esté bien, pero YMMV así que ten mucho cuidado.


2
2018-03-01 14:12