Makefile para compilar múltiples programas en C?

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

program1:
    gcc -o prog1 program1.c

program2:
    gcc -o prog2 program2.c

¡Todos los ejemplos en línea contienen 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?

preguntado el 10 de mayo de 11 a las 12:05

Las respuestas a continuación son muy claras, pero también puede ejecutar la línea de comando: make program1 program2 que invocará ambos objetivos en el mismo ejemplo que se dio a sí mismo. Si solo quieres program1, puedes correr solo make (ejecutará el primer objetivo). Si solo quieres program2, correr 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. -

8 Respuestas

Hazlo asi

all: program1 program2

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

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

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

all: program1 program2

program1: program1.c
program2: program2.c

contestado el 10 de mayo de 11 a las 17:05

Tenga en cuenta que si desea que ambos programas se generen automáticamente, all target debe aparecer antes que los programas individuales en el archivo MAKE y ser el primer objetivo en el archivo MAKE. - Randall Cook

Puedes poner all o cualquier otro objetivo donde desee y conviértalo en el predeterminado para ejecuciones sin objetivo (lo que llamó "automático") de make usar .DEFAULT_GOAL:=all. - subrayado_d

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

objects = program1 program2
all: $(objects)

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

Respondido el 08 de enero de 18 a las 19:01

En lugar de program1 y program2, ¿qué pasa si tiene miles de archivos ".c" en varios directorios, subdirectorios? ¿Cómo podemos automatizar lo mismo usando la lógica anterior? - SH '

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

@hmofrad responde con 'tr' eliminará todos los caracteres coincidentes ['.', 'c'], no una subcadena. Arreglar: find tests/ -type f -iname '*.cpp' | sed 's/.cpp//g' - Ben Crowhurst

############################################################################
# '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

Respondido el 04 de diciembre de 12 a las 08:12

Gracias por el código anterior. Lo uso para compilar mis archivos .c. Pero si cambio alguno de mis archivos myHeader.h, entonces necesito volver a guardar un archivo .c antes de usar 'make' o de lo contrario 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 compilar después de cualquier cambio en los archivos .h sin volver a guardar el archivo .c? y gracias por el código anterior !!! - jatin3893

Gracias. Esto fue muy útil para mí :) - SHRI

¡Gracias, esto es lo que estaba buscando! - ElBaulP

"$ (OBJS) debería eliminarse automáticamente después de la vinculación". ¿No conduce eso a una recopilación innecesaria y, por lo tanto, en su mayoría anula el punto make? - subrayado_d

¿Por qué necesitas? .SECONDEXPANSION? - crisron

all: program1 program2

program1:
    gcc -Wall -o prog1 program1.c

program2:
    gcc -Wall -o prog2 program2.c

contestado el 10 de mayo de 11 a las 17:05

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 pedante, un mejor control para su programa. ¡No le permitirá compilar mientras todavía tenga advertencias!

contestado el 10 de mayo de 11 a las 17:05

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

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

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

Cuando lanzas make, se lee Makefile, y comprueba si ha cambiado archivos. Si hay alguno, activa el gobernar, que depende de ello. El gobernar puede producir / actualizar más archivos, que puede desencadenar otros reglas etcétera. Si crea un buen archivo MAKE, solo lo necesario reglas (comandos de compilador / enlace) se ejecutará, que está "al siguiente" del archivo modificado en la ruta de dependencia.

Elige un ejemplo Makefile, lea el manual para conocer la sintaxis (de todos modos, está claro a primera vista, sin manual), y dibuja el gráfico. Debe comprender las opciones del compilador para saber los nombres de los archivos de resultados.

El gráfico de creación debe ser tan complejo como desee. ¡Incluso puedes hacer bucles infinitos (no lo hagas)! Puedes decir hacer, cual regla es tu objetivo, así que solo los que quedan archivos se utilizarán como desencadenantes.

De nuevo: dibuja el gráfico!.

contestado el 10 de mayo de 11 a las 17:05

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

make agregará automáticamente las banderas que agregue a CFLAGS como 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)

Respondido 20 Abr '20, 19:04

SRC = a.cpp b.cpp
BIN = $(patsubst %.cpp,%,$(SRC))

all: $(BIN)

clean:
    rm -f $(BIN)

.PHONY: all clean

make all servirá:

c++     a.cpp   -o a
c++     b.cpp   -o b

Si configura CXX y CXXFLAGS las variables make los usará.

respondido 10 mar '17, 06:03

Querías decir a.cpp -o a? - Shane Abram Méndez

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.