Makefile para compilar múltiples programas en C?

6 minutos de lectura

avatar de usuario
Sara

Esta es una pregunta increíblemente simple, pero soy nuevo en makefiles. Estoy tratando de hacer un archivo MAKE que compilará dos programas independientes:

program1:
    gcc -o prog1 program1.c

program2:
    gcc -o prog2 program2.c

¡Todos los ejemplos en línea incluyen muchos más detalles de los que necesito y son confusos! Todo lo que realmente quiero que haga es ejecutar los dos gcc líneas. ¿Qué estoy haciendo mal?

  • Las respuestas a continuación son muy claras, pero también puede ejecutar la línea de comando: make program1 program2 eso invocará a ambos objetivos en el mismo ejemplo que te diste a ti mismo. si solo quieres program1puedes correr solo make (se ejecutará el primer objetivo). si solo quieres program2correr make program2. Tienes más control. Y por supuesto, un objetivo all: program1 program2 hará exactamente eso (siendo el primero, ejecutando sus otros 2 objetivos). Hecho.

    – DrBeco

    16 de junio de 2016 a las 5:31

Hazlo así

all: program1 program2

program1: program1.c
    gcc -o program1 program1.c

program2: program2.c
    gcc -o program2 program2.c

Dijiste que no quieres cosas avanzadas, pero también podrías acortarlo de esta manera según algunas reglas predeterminadas.

all: program1 program2

program1: program1.c
program2: program2.c

  • Tenga en cuenta que si desea que ambos programas se construyan automáticamente, el all target debe aparecer antes que los programas individuales en el archivo MAKE y ser el primer destino en el archivo MAKE.

    – Randall Cook

    8 de enero de 2014 a las 2:15

  • Puedes poner all o cualquier otro destino que desee y conviértalo en el valor predeterminado para ejecuciones sin destino (lo que llamó “automático”) de make utilizando .DEFAULT_GOAL:=all.

    – subrayado_d

    19/09/2015 a las 21:08


avatar de usuario
hmofrad

Reglas de patrón le permite compilar múltiples archivos c que requieren los mismos comandos de compilación usando make como sigue:

objects = program1 program2
all: $(objects)

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

  • En lugar de program1 y program2, ¿qué sucede si tiene miles de archivos “.c” en varios directorios, subdirectorios? ¿Cómo podemos automatizar lo mismo usando la lógica anterior?

    – SH’

    22 de enero de 2021 a las 16:19

  • @SH’ Usar marca shell comando para llenar objects utilizando la salida de find. P.ej, objects := $(shell find . -type f -iname "*.c" -print | tr -d ".c" | sed 's/\///')

    – hmofrad

    22 de enero de 2021 a las 18:33


  • La respuesta de @hmofrad con ‘tr’ eliminará todos los caracteres coincidentes [‘.’, ‘c’], no una subcadena. Reparar: find tests/ -type f -iname '*.cpp' | sed 's/.cpp//g'

    – Ben Crowhurst

    1 de julio de 2021 a las 3:47


avatar de usuario
Roberto

############################################################################
# 'A Generic Makefile for Building Multiple main() Targets in $PWD'
# Author:  Robert A. Nader (2012)
# Email: naderra at some g
# Web: xiberix
############################################################################
#  The purpose of this makefile is to compile to executable all C source
#  files in CWD, where each .c file has a main() function, and each object
#  links with a common LDFLAG.
#
#  This makefile should suffice for simple projects that require building
#  similar executable targets.  For example, if your CWD build requires
#  exclusively this pattern:
#
#  cc -c $(CFLAGS) main_01.c
#  cc main_01.o $(LDFLAGS) -o main_01
#
#  cc -c $(CFLAGS) main_2..c
#  cc main_02.o $(LDFLAGS) -o main_02
#
#  etc, ... a common case when compiling the programs of some chapter,
#  then you may be interested in using this makefile.
#
#  What YOU do:
#
#  Set PRG_SUFFIX_FLAG below to either 0 or 1 to enable or disable
#  the generation of a .exe suffix on executables
#
#  Set CFLAGS and LDFLAGS according to your needs.
#
#  What this makefile does automagically:
#
#  Sets SRC to a list of *.c files in PWD using wildcard.
#  Sets PRGS BINS and OBJS using pattern substitution.
#  Compiles each individual .c to .o object file.
#  Links each individual .o to its corresponding executable.
#
###########################################################################
#
PRG_SUFFIX_FLAG := 0
#
LDFLAGS := 
CFLAGS_INC := 
CFLAGS := -g -Wall $(CFLAGS_INC)
#
## ==================- NOTHING TO CHANGE BELOW THIS LINE ===================
##
SRCS := $(wildcard *.c)
PRGS := $(patsubst %.c,%,$(SRCS))
PRG_SUFFIX=.exe
BINS := $(patsubst %,%$(PRG_SUFFIX),$(PRGS))
## OBJS are automagically compiled by make.
OBJS := $(patsubst %,%.o,$(PRGS))
##
all : $(BINS)
##
## For clarity sake we make use of:
.SECONDEXPANSION:
OBJ = $(patsubst %$(PRG_SUFFIX),%.o,$@)
ifeq ($(PRG_SUFFIX_FLAG),0)
        BIN = $(patsubst %$(PRG_SUFFIX),%,$@)
else
        BIN = $@
endif
## Compile the executables
%$(PRG_SUFFIX) : $(OBJS)
    $(CC) $(OBJ)  $(LDFLAGS) -o $(BIN)
##
## $(OBJS) should be automagically removed right after linking.
##
veryclean:
ifeq ($(PRG_SUFFIX_FLAG),0)
    $(RM) $(PRGS)
else
    $(RM) $(BINS)
endif
##
rebuild: veryclean all
##
## eof Generic_Multi_Main_PWD.makefile

  • Gracias por el código anterior. Lo uso para compilar mis archivos .c. Pero si cambio cualquiera de mis archivos myHeader.h, entonces necesito volver a guardar el archivo .c antes de usar ‘make’ o muestra “make: Nothing to be done for ‘all'”. mientras que en realidad se han realizado cambios en el archivo .h. ¿Podemos modificar el archivo make para compilarlo después de cualquier cambio en los archivos .h sin volver a guardar el archivo .c? y gracias por el código anterior!

    – jatin3893

    3 de febrero de 2013 a las 15:09

  • Gracias. Esto fue muy útil para mí 🙂

    – SHRI

    29 de julio de 2013 a las 14:26

  • Gracias, esto es lo que estaba buscando!

    –Alejandro Alcalde

    23 de marzo de 2014 a las 10:14

  • “$(OBJS) debe eliminarse automáticamente justo después de la vinculación”. ¿No lleva eso a una recompilación innecesaria y, por lo tanto, en gran medida anula el punto de make?

    – subrayado_d

    19/09/2015 a las 21:07

  • ¿Por qué necesitas .SECONDEXPANSION?

    – Crisrón

    16 de julio de 2016 a las 10:19

all: program1 program2

program1:
    gcc -Wall -o prog1 program1.c

program2:
    gcc -Wall -o prog2 program2.c

all: program1 program2

program1:
    gcc -Wall -ansi -pedantic -o prog1 program1.c

program2:
    gcc -Wall -ansi -pedantic -o prog2 program2.c

Prefiero el ansi y el pedante, un mejor control para tu programa. ¡No le permitirá compilar mientras aún tenga advertencias!

  • eso no es lo que -pedantic es para. -pedantic eliminará cualquier característica que no sea ANSI que incluso -ansi permisos

    – cnicutar

    10 mayo 2011 a las 13:15

  • Para agregar al comentario de cnicutar, -Werror cambiará las advertencias por errores.

    – jtniehof

    10 de mayo de 2011 a las 14:09

avatar de usuario
ern0

El flujo de trabajo de compilación de un programa simple es simple, puedo dibujarlo como un pequeño gráfico: fuente -> [compilation] -> objeto [linking] -> ejecutable. Hay archivos (fuente, objeto, ejecutable) en este gráfico, y normas (hacerterminología de ). Ese gráfico se define en el Makefile.

Cuando ejecutas make, se lee Makefiley comprueba si hay cambios archivos. Si hay alguno, desencadena el regla, que depende de ello. los regla puede producir/actualizar más archivosque puede desencadenar otros normas y así. Si crea un buen makefile, solo lo necesario normas (Compilador/comandos de enlace) se ejecutará, que se encuentra “al siguiente” del archivo modificado en la ruta de dependencia.

elige un ejemplo Makefilelea el manual de sintaxis (de todos modos, está claro a primera vista, sin manual), y dibujar el gráfico. Debe comprender las opciones del compilador para averiguar los nombres de los archivos de resultados.

El gráfico make debe ser tan complejo como quieras. ¡Incluso puedes hacer bucles infinitos (no lo hagas)! Puedes decir hacerque regla es tu objetivopor lo que sólo la izquierda archivos se utilizarán como disparadores.

Otra vez: dibujar el gráfico!.

  • eso no es lo que -pedantic es para. -pedantic eliminará cualquier característica que no sea ANSI que incluso -ansi permisos

    – cnicutar

    10 mayo 2011 a las 13:15

  • Para agregar al comentario de cnicutar, -Werror cambiará las advertencias por errores.

    – jtniehof

    10 de mayo de 2011 a las 14:09

Esto compilará todo *.c archivos sobre make a ejecutables sin la .c extensión como en gcc program.c -o program.

make agregará automáticamente cualquier bandera que agregue a CFLAGS me gusta CFLAGS = -g Wall.

Si no necesitas banderas CFLAGS puede dejarse en blanco (como se muestra a continuación) u omitirse por completo.

SOURCES = $(wildcard *.c)
EXECS = $(SOURCES:%.c=%)
CFLAGS = 

all: $(EXECS)

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad