¿Cómo hago un simple archivo MAKE para gcc en Linux?

130

Tengo tres archivos: program.c, program.hy headers.h.

program.cincluye program.hy headers.h.

Necesito compilar esto en Linux usando el compilador gcc . No estoy seguro de cómo hacer esto. Netbeans creó uno para mí, pero está vacío.

usuario69514
fuente
1
Hay una solución extremadamente elegante (y bien documentada) en spin.atomicobject.com/2016/08/26/makefile-c-projects .
Casey

Respuestas:

193

Interesante, no sabía que make usaría de manera predeterminada las reglas dadas del compilador de C con respecto a los archivos fuente.

De todos modos, una solución simple que demuestra conceptos simples de Makefile sería:

HEADERS = program.h headers.h

default: program

program.o: program.c $(HEADERS)
    gcc -c program.c -o program.o

program: program.o
    gcc program.o -o program

clean:
    -rm -f program.o
    -rm -f program

(tenga en cuenta que make requiere una pestaña en lugar de una sangría de espacio, así que asegúrese de arreglar eso al copiar)

Sin embargo, para admitir más archivos C, tendría que crear nuevas reglas para cada uno de ellos. Por lo tanto, para mejorar:

HEADERS = program.h headers.h
OBJECTS = program.o

default: program

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

program: $(OBJECTS)
    gcc $(OBJECTS) -o $@

clean:
    -rm -f $(OBJECTS)
    -rm -f program

Intenté hacer esto lo más simple posible omitiendo variables como $ (CC) y $ (CFLAGS) que generalmente se ven en los archivos MAKE. Si estás interesado en resolver eso, espero haberte dado un buen comienzo.

Aquí está el Makefile que me gusta usar para la fuente C. Sientase libre de usarlo:

TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall

.PHONY: default all clean

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)

%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) -c $< -o $@

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    -rm -f *.o
    -rm -f $(TARGET)

Utiliza las características comodín y patsubst de la utilidad make para incluir automáticamente archivos .c y .h en el directorio actual, lo que significa que cuando agrega nuevos archivos de código a su directorio, no tendrá que actualizar el Makefile. Sin embargo, si desea cambiar el nombre del ejecutable generado, las bibliotecas o los indicadores del compilador, puede modificar las variables.

En cualquier caso, no use autoconf, por favor. ¡Te lo ruego! :)

Joey Adams
fuente
77
Para ser técnicamente correcto, creo que deberías usarlo .PHONY: clean all defaultpara esos objetivos que están destinados a ser usados ​​desde la línea de comando. Además, Autoconf / Automake no son tan malos. Claro, se sienten horribles, y acostumbrarse a ellos es tan divertido como forzar la cabeza a través de una pared de ladrillos, pero funcionan, y están bien desarrollados, y cubrirán la mayoría de sus bases en cuanto a portabilidad, y hará que tu vida sea mucho más fácil al final una vez que te acostumbres a su horrible diseño.
Chris Lutz
Supongo que esto funciona, pero pensé que si escribía "make" en el terminal, el programa debería ejecutarse. Esto es lo que obtengo: gcc statsh.o -Wall -lm -o prog ¿Es posible escribir make y ejecutar el programa?
user69514
¿dónde añadir el -fopenmp bandera openmp
MySchizoBuddy
1
¿Por qué no usar autoconf joey-adams?
Michal Gonda
77
Si alguien se pregunta por qué hay guiones delante de rm: stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
Tor Klingberg
25

Por ejemplo, este simple Makefile debería ser suficiente:

CC = gcc 
CFLAGS = -Wall

todos: programa
programa: programa.o
program.o: program.c program.h headers.h

limpiar:
    rm -f program program.o
ejecute el programa
    ./programa

Tenga en cuenta que debe haber <tab>en la siguiente línea después de limpiar y ejecutar, no espacios.

ACTUALIZACIÓN Comentarios a continuación aplicados

Viliam
fuente
@ user69514: makesin argumentos, generalmente solo construye su software. Para ejecutarlo, use make run(disponible en esta respuesta, pero no necesariamente en todas Makefile), o ejecútelo directamente:./program
MestreLion
14
all: program
program.o: program.h headers.h

es suficiente. el resto es implícito

anónimo
fuente
1
Y si todo su programa es un solo .carchivo, solo program:es necesario. Dulce :)
MestreLion
10

El archivo de creación más simple puede ser

all : test

test : test.o
        gcc -o test test.o 

test.o : test.c
        gcc -c test.c

clean :
        rm test *.o
Indrakumar
fuente
puedes agregar más detalles para explicar lo que hace tu Makefile
Federico
2
en realidad puedes ser mucho más simple. ver @anonymous 1 liner
Mark Lakata
0

Dependiendo de la cantidad de encabezados y sus hábitos de desarrollo, es posible que desee investigar gccmakedep. Este programa examina su directorio actual y agrega al final del archivo MAKE las dependencias de encabezado para cada archivo .c / cpp. Esto es excesivo cuando tienes 2 encabezados y un archivo de programa. Sin embargo, si tiene más de 5 pequeños programas de prueba y está editando uno de los 10 encabezados, puede confiar en make para reconstruir exactamente aquellos programas que fueron modificados por sus modificaciones.


fuente