2008-11-13 20 views
19

He estado buscando un simple archivo "mínimo" de C++ makefile recomendado para Linux que usará g ++ para compilar y vincular un solo archivo y un archivo h. Lo ideal es que el archivo make ni siquiera tenga los nombres de los archivos físicos y solo tenga una transformación de .cpp a .o. ¿Cuál es la mejor manera de generar un archivo MAKE sin sumergirse en los horrores de autoconf?mínimo C++ make file for linux

El directorio actual contiene, por ejemplo

T.cpp t.h

y quiero un makefile para que se va a crear. Intenté autoconf, pero su suponer .h es gcc en lugar de g ++. Sí, aunque no soy un principiante, estoy volviendo a aprender desde hace años los mejores enfoques para la manipulación de proyectos y, por lo tanto, estoy buscando formas automatizadas para crear y mantener archivos MAKE para proyectos pequeños.

+0

Make es ideal para proyectos sencillos (y para jugar). Pero mantener un gran proyecto se vuelve difícil de hacer correctamente (puedes hudge podge fácilmente pero correctamente es difícil). Use herramientas como 'scons' para construir su archivo make –

+0

scons se ve bien. Ciertamente más fácil que Autoconf. – RichieHH

+1

OMake es genial y se hace cargo cuando make muestra sus límites. – bltxd

Respuesta

27

Si es un solo archivo, puede escribir

make t 

Y invocará

g++ t.cpp -o t 

Esto ni siquiera requiere un Makefile en el directorio, aunque se confundirá si usted tiene un T.cpp y una TC y una t.java, etc, etc

también un verdadero Makefile:

SOURCES := t.cpp 
# Objs are all the sources, with .cpp replaced by .o 
OBJS := $(SOURCES:.cpp=.o) 

all: t 

# Compile the binary 't' by calling the compiler with cflags, lflags, and any libs (if defined) and the list of objects. 
t: $(OBJS) 
    $(CC) $(CFLAGS) -o t $(OBJS) $(LFLAGS) $(LIBS) 

# Get a .o from a .cpp by calling compiler with cflags and includes (if defined) 
.cpp.o: 
    $(CC) $(CFLAGS) $(INCLUDES) -c $< 
+1

esto tampoco crea ninguna dependencia. –

+0

Este archivo MAKE es casi (pero no del todo) equivalente a "all: t" y deja que las reglas incorporadas se hagan cargo ... –

+0

¿Pero por qué tienes una regla específica para t:? De alguna manera, derrota el punto de tener una regla cpp.o. – RichieHH

8

¿Has mirado SCons?

Basta con crear un archivo SConstruct con lo siguiente:

Program("t.cpp") 

a continuación, escriba:

scons 

hecho!

+0

Aunque me encanta jugar con makefile (es un lenguaje en sí mismo). Creo que esta es la mejor respuesta, pero creo que debes ampliar esta respuesta un poco para explicar por qué usar "SCons" es mejor que usar Makefiles directamente. Estoy convencido, pero aquí no hay suficiente para convencer a otros. –

4

suponiendo que no hay make configuración de todo el sistema preconfigurados:

CXX = g++ 
CPPFLAGS =  # put pre-processor settings (-I, -D, etc) here 
CXXFLAGS = -Wall # put compiler settings here 
LDFLAGS =   # put linker settings here 

test: test.o 
    $(CXX) -o [email protected] $(CXXFLAGS) $(LDFLAGS) test.o 

.cpp.o: 
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< 

test.cpp: test.h 
+0

De nuevo esta es una línea específica para la prueba. ¿Por qué? – RichieHH

+0

porque siempre debe especificar * qué * el archivo Makefile realmente generará. Con defs globales adecuados, puede simplemente decir simplemente "prueba:" en el archivo, pero se garantiza que el archivo anterior funcionará independientemente de las reglas o macros globales. – Alnitak

-1

Si sus problemas se deben a que autoconf piensa del archivo .h es AC, tratan de cambiar el nombre a .hpp o .h ++

16

Aquí es un makefile genérica de mi fragmentos de código directorio:

SOURCES=$(wildcard *.cpp) 
OBJECTS=$(SOURCES:.cpp=.o) 
DEPS=$(SOURCES:.cpp=.d) 
BINS=$(SOURCES:.cpp=) 

CFLAGS+=-MMD 
CXXFLAGS+=-MMD 

all: $(BINS) 

.PHONY: clean 

clean: 
    $(RM) $(OBJECTS) $(DEPS) $(BINS) 

-include $(DEPS) 

Como siempre y cuando tenga una fuente .cpp producir un binario, no es necesario nada más.Solo lo he usado con GNU make, y la generación de dependencias usa la sintaxis gcc (también compatible con icc). Si está utilizando los compiladores de SUN, debe cambiar "-MMD" a "-xMMD". Además, asegúrese de que la pestaña al comienzo de la línea después de clean: no se cambie a espacios cuando pegue este código o make le dará un error de separación faltante.

0

SConstruct con la opción de depuración:

env = Environment() 

if ARGUMENTS.get('debug', 0): 
    env.Append(CCFLAGS = ' -g') 

env.Program(source = "template.cpp") 
0

Florin tiene un buen punto de partida. No me gn autoconf gnu así que comencé allí y llevé el concepto más allá y lo llamé MagicMakefile. Tengo 3 versiones de simple a más compleja. Lo último está ahora en github: https://github.com/jdkoftinoff/magicmake

Básicamente, supone que tiene un diseño estándar para los archivos fuente de su proyecto y usa la función comodín para crear las reglas de makefile sobre la marcha que luego se evalúan, manejando el encabezado dependencias de archivo, compilación cruzada, pruebas unitarias, instalación y empaque.

[edit] En este punto utilizo cmake para todos mis proyectos, ya que genera archivos de proyecto útiles para muchos sistemas de compilación.

Jeff koftinoff

+0

¡Uy! Perdón por los enlaces rotos. Lo moví a Github. https://github.com/jdkoftinoff/magicmake - Dicho esto, ahora uso CMake. – jdkoftinoff

1

¿Has mirado en OMake?

OMakeroot

open build/C 
DefineCommandVars() 
.SUBDIRS: . 

OMakefile

.DEFAULT: $(CXXProgram test, test) 

Entonces en Linux o Windows, simplemente escriba:

omake 

Como beneficio adicional, se obtiene automáticamente:

  • compilaciones paralelas con la opción -j (igual que make).
  • Sumas de comprobación MD5 en lugar de marcas de tiempo (la construcción se vuelve resistente a las fallas de sincronización de tiempo).
  • Dependencias de encabezado C/C++ automáticas y precisas.
  • Dependencias precisas entre directorios (algo que recursive make no ofrece).
  • Portabilidad (1 cadena de construcción para controlarlos a todos, inmune a los problemas de estilo de ruta).
  • Un lenguaje de programación real (mejor que la marca GNU).
+0

Si OMake tuviera un mejor soporte para compilaciones fuera de la fuente y pudiera generar el proyecto de Visual Studio, sería muy similar a perfecto. – JesperE

+0

Hacemos construcciones fuera de la fuente con OMake aquí. Hay algunas cosas que debe saber, pero de lo contrario, funciona (0.9.8.5). – bltxd

1

bastante pequeña GNU Makefile, usando reglas predefinidas y auto-deps:

CC=c++ 
CXXFLAGS=-g -Wall -Wextra -MMD 
LDLIBS=-lm 
program: program.o sub.o 
clean: 
    $(RM) *.o *.d program 
-include $(wildcard *.d) 
0

estaba cazando alrededor por lo que un Makefile mínima podría parecer que no sea

some_stuff: 
    @echo "Hello World" 

que sé Llego tarde a esta fiesta, pero pensé que también lanzaría mi sombrero al ring. El siguiente es mi proyecto de directorio Makefile que he usado durante años. Con una pequeña modificación, escala para usar múltiples directorios (por ejemplo, src, obj, bin, header, test, etc.).Asume que todos los encabezados y archivos fuente están en el directorio actual. Y tiene que darle un nombre al proyecto que se usa para el nombre binario de salida.

NAME = my_project 

FILES = $(shell basename -a $$(ls *.cpp) | sed 's/\.cpp//g') 
SRC = $(patsubst %, %.cpp, $(FILES)) 
OBJ = $(patsubst %, %.o, $(FILES)) 
HDR = $(patsubst %, -include %.h, $(FILES)) 
CXX = g++ -Wall 

%.o : %.cpp 
     $(CXX) $(HDR) -c -o [email protected] $< 

build: $(OBJ) 
     $(CXX) -o $(NAME) $(OBJ) 

clean: 
     rm -vf $(NAME) $(OBJ)