Pregunta Crear archivo para una estructura de directorios más grande


Tengo varios directorios con subdirectorios que contienen archivos c o asm y los quiero compilados / ensamblados y luego vinculados. No soy especialmente quisquilloso con los archivos objeto (por ejemplo, una carpeta bin especial o en la carpeta src) siempre que make clean los elimine a todos.

La estructura se vería así:

/src
    /dir1
        /dir1_1
            +file1_1.s
            +file1_2.s
        +file1.s
    /dir2
        +file2.c

Estoy seguro de que hay una manera fácil de crear un archivo MAKE que compila todos los archivos sin que tenga que especificar dónde debe verse (compilar todos los archivos en un directorio es posible con comodines, pero ¿qué ocurre entonces?).


5
2018-02-20 02:26


origen


Respuestas:


Si su proyecto es lo suficientemente pequeño, puede salirse con la suya con un archivo makefile único hecho a mano en lugar de un sistema de compilación más sofisticado: revise el página de manual sobre funciones de transformación para ver lo que es posible.

Su proyecto de ejemplo podría compilarse con el siguiente archivo make no recursivo:

targets = $(patsubst %$(1),%$(2),$(foreach dir,$(3),$(wildcard $(dir)/*$(1))))

asmdirs := src/dir1 src/dir1/dir1_1
cdirs := src/dir2

asmobjects := $(call targets,.s,.o,$(asmdirs))
cobjects := $(call targets,.c,.o,$(cdirs))

.PHONY : all clean

all : $(asmobjects) $(cobjects)

clean :
    rm -f $(asmobjects) $(cobjects)

$(cobjects) : %.o : %.c
    gcc -o $@ -c $<

$(asmobjects) : %.o : %.s
    gcc -o $@ -c $<

Sin embargo, porque make puede acceder al shell, también puede usar herramientas estándar de Unix como find en lugar de las funciones internas algo limitadas, por ejemplo

asmsources := $(shell find src -name '*.s')
csources := $(shell find src -name '*.c')

asmobjects := $(asmsources:.s=.o)
cobjects := $(csources:.c=.o)

4
2018-02-20 14:48



Haga una búsqueda en Google para 'recursivo hacer considerado perjudicial'. Encontrará el artículo original que postula que el procedimiento recursivo es una mala forma de hacer negocios, y encontrará algunos enlaces a otros lugares que debaten la validez de la proposición.

Básicamente, hay dos formas de hacer construcciones en una jerarquía de directorios (con make)

  1. Marca recursiva: cada directorio contiene un archivo MAKE que se compila en subdirectorios y luego se crea en el directorio actual.
  2. Marca no recursiva: el archivo MAKE incluye todos los archivos MAKE dependientes, y construye la estructura de dependencia completa para todo el proyecto y solo crea el software requerido.

Trabajo rutinariamente en un producto en el que la secuencia de compilación principal está impulsada por un sistema híbrido que utiliza un script de shell más un archivo MAKE para cada directorio. Una sección del producto es administrada por un archivo MAKE 'RMCH'; la mayor parte no lo es. La secuencia de comandos de compilación se ocupa de las fases de la construcción y las secuencias de los directorios, y se ejecuta make en cada directorio cuando es el momento de hacerlo. (El código fuente está en 20k + archivos distribuidos en una multitud de directorios; es un gran proyecto / producto).

También he convertido un proyecto mediano-pequeño (alrededor de 20 directorios de relevancia y cerca de 400 archivos fuente) para trabajar con RMCH (desde un script + archivo makefile-por-directorio). Fue un poco alucinante al principio, pero funciona bastante bien ahora que está hecho. Si lo hice correctamente está abierto para el debate; fue principalmente un ejercicio de aprendizaje, aunque también modifiqué el código para trabajar con una biblioteca de maldiciones moderna en lugar de la biblioteca arcaica de BSD que se usaba como parte del código (arcaico, como en 1982-vintage; el código era último seriamente desarrollado en alrededor de 1986) y en general actualizar a estándares modernos (estándar C). También fue una oportunidad de trabajar con git - Entonces, en general, una experiencia de aprendizaje bastante extensa.

Si puede envolver su cerebro en torno a RMCH, es un buen sistema. Si se hace correctamente, con un seguimiento de dependencias completo y preciso, elimina las suposiciones de la secuencia de compilación, y se ejecuta rápidamente. Sin embargo, migrar incluso un proyecto de tamaño mediano es un trabajo bastante difícil: sería una tarea abrumadora hacerlo en el producto principal en el que trabajo, aunque el sistema podría beneficiarse de ello.

Una alternativa es mirar otras alternativas para make, como cmake, rake, scons, bras, imake, o ant o lo que sea que más te guste. La mayoría de ellos son fácilmente detectables a través de una búsqueda en Google; el dificil es bras, que se basa en Tcl (como en Tcl / Tk), pero probablemente ya haya muerto en gran parte. Y imake Se menciona más para completar que como una sugerencia seria. También puede consultar los Autotools de GNU. Los que no abandonan make; construyen encima make.


5
2018-02-20 06:19