2011-03-16 21 views
5

que estoy haciendo algunos refactorización Makefile y tratando de averiguar la forma más concisa para implementar un Makefile que hace lo siguiente:un diccionario Makefile

  1. Tiene una variable que tiene todos los archivos de fuentes incluidas (puede ser a la vez C y C++ archivos)
  2. Todos los archivos de objetos se generan en OBJ_DIR
  3. La lista de objetos se crea si no existe

Esto es lo que tengo hasta ahora:

... 

OBJ_DIR = obj/ 
BIN_DIR = bin/ 
PROGRAM = program 

SRCS = test1.cpp test2.c 

OBJS = $(addprefix $(OBJ_DIR), \ 
     $(patsubst %.cpp, %.o, \ 
     $(patsubst %.c, %.o, $(SRCS)))) 

$(BIN_DIR)$(PROGRAM) : $(OBJS) 
    $(CREATE_OUT_DIR) 
    $(LINK) 

$(OBJ_DIR)%.o : %.c 
    $(CREATE_OBJ_DIR) 
    $(CCOMPILE) 

$(OBJ_DIR)%.o : %.cpp 
    $(CREATE_OBJ_DIR) 
    $(CPPCOMPILE) 

... 

Me gustaría eliminar la llamada a $ (CREATE_OBJ_DIR) para cada compilación .o. Alguien sabe cómo hacer esto? He intentado añadir esto, pero entonces no sería construir los archivos de objetos:

$(OBJS): | $(OBJ_DIR) 

$(OBJ_DIR): 
    $(CREATE_OBJ_DIR) 
+0

Veo problemas con este diseño. ¿Cómo se contabilizan las dependencias del encabezado? Normalmente escribo makefiles con algo como 'src = $ (shell find ./ --name" * .cpp ")' y uso los conmutadores GCC '-M' para tener dependencias manejadas por mí. De esta manera, tengo un archivo make reutilizable corto para todos mis proyectos. En cuanto a su problema real, ¿por qué no crear el directorio 'obj' de antemano? –

+0

No es exactamente una respuesta, pero ¿ya has visto alternativas a 'Makefile'? 'SConstruct' viene a mi mente (y es genial) pero hay muchas otras herramientas que manejan muy bien ese tipo de problemas. – ereOn

+0

@Alexandre: también iba a examinar las dependencias de encabezado. ¿Tienes un buen ejemplo de cómo hacer esto? – waffleman

Respuesta

3

Ya parecen haber resuelto su primer punto: tener a todos ellos en una variable (que no debería pensar que realmente se necesita para separarlas en TEMP 1 y TEMP2 como usted ha, simplemente tienen diferentes reglas de generación)

para el segundo punto, se puede decir que el compilador de salida de las archivos de objetos (por g ++ es como esto:

g++ -c MySourceFile.cpp -o obj/MySourceFile.o 

la regla de maquillaje para este sería el resultado:

obj/%.o: %.cpp 
    g++ -c $*.cpp -o obj/$*.o 

Y su tercer punto también se resuelve fácilmente, ya que puede tener una regla de compilación (simplemente coloque el nombre del directorio en la lista de dependencia para el destino, antes de que todos los objetos estén listados), y la regla de compilación se vería así

obj: 
    mkdir obj 

Editar: o sus siguientes ejemplos de código:

$(BIN_DIR)$(PROGRAM) : $(BIN_DIR) $(OBJS) 
$(LINK) 

$(BIN_DIR): 
    $(CREATE_OUT_DIR) 
+0

La dependencia del directorio debe ser una dependencia de solo orden. –

+0

Comprimí la generación de la lista de archivos del objeto en un solo comando.Gracias por el consejo. – waffleman

1

En cuanto a su tercera cuestión: Esta pregunta tiene been asked here before. Desafortunadamente, no hay una respuesta realmente buena para esto, y necesitas encontrar el truco menos feo de la respuesta. Personalmente, voto por la solución de archivo marcador.

0

Esto es lo que hago:

$(OBJ_LOC)/%.o: $(SRC_LOC)/%.c 
    @[ -d $(OBJ_LOC) ] || mkdir -p $(OBJ_LOC) 
    g++ ... 

Pero, estoy mirando estas otras respuestas con gran inte descanso.