2009-04-27 20 views
22

Soy nuevo en makefiles. Aprendí creación de archivos y otros conceptos relacionados del libro "Gestionar proyectos con GNU make". El archivo MAKE está listo ahora y necesito asegurarme de que el que creé esté BIEN. Aquí está el archivo MAKEArchivo simple con versiones de lanzamiento y depuración - Mejores prácticas

#Main makefile which does the build 

#makedepend flags 
DFLAGS = 

#Compiler flags 
#if mode variable is empty, setting debug build mode 
ifeq ($(mode),release) 
    CFLAGS = -Wall 
else 
    mode = debug 
    CFLAGS = -g -Wall 
endif 

CC = g++ 
PROG = fooexe 

#each module will append the source files to here 
SRC := main.cpp 

#including the description 
include bar/module.mk 
include foo/module.mk 

OBJ := $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC))) 

.PHONY:all 
all: information fooexe 

information: 
ifneq ($(mode),release) 
ifneq ($(mode),debug) 
    @echo "Invalid build mode." 
    @echo "Please use 'make mode=release' or 'make mode=debug'" 
    @exit 1 
endif 
endif 
    @echo "Building on "$(mode)" mode" 
    @echo ".........................." 

#linking the program 
fooexe: $(OBJ) 
    $(CC) -o $(PROG) $(OBJ) 

%.o:%.cpp 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

depend: 
    makedepend -- $(DFLAGS) -- $(SRC) 

.PHONY:clean 
clean: 
    find . -name "*.o" | xargs rm -vf 
    rm -vf fooexe 

Preguntas

  1. El makefile dado anteriormente funciona bien con la liberación y versiones de depuración. ¿Pero está en el formato correcto? ¿O ves algún defecto en eso?
  2. Por encima de makefile depura la compilación de forma predeterminada cuando se invoca utilizando make. Para compilaciones de lanzamiento, make mode = release es obligatorio. ¿Es este el enfoque correcto?
  3. ¿Los indicadores del compilador de depuración y liberación suministrados a g ++ son correctos? Para la depuración, uso -g -Wall y, para su lanzamiento, solo -Wall. ¿Es esto correcto?

Cualquier ayuda sería genial.

+0

¿Está pensando en liberar la fuente de su software, incluido el Makefile? ¿O solo estás enviando binarios? es decir. ¿Alguien más que tú y tu equipo verán y usarán este Makefile? – Schwern

+0

Sí. Voy a lanzar el código fuente ya que este será un proyecto de código abierto. –

Respuesta

13
  1. Es un formato razonable. Está vinculado específicamente a GNU Make, pero ese es un problema relativamente menor si ha elegido usar GNU Make en todas las plataformas.
    • Si hay un error, es que podría terminar vinculando archivos de objetos creados en modo de depuración para crear la compilación final.
    • Algunos podrían argumentar que una opción 'mode = release' no es estándar; Tendrían razón, pero no hay una alternativa estándar de la que sea consciente. Solo debe tener en cuenta que su convención podría no ser adecuada para todos (pero no tiene que ser así, solo tiene que adaptarse a usted y a sus usuarios).
  2. Crear una compilación de depuración de forma predeterminada es probablemente sensato, y más sensato que crear la versión de la versión de manera predeterminada.
  3. Dejar caer el indicador -g para la compilación de lanzamiento no es automáticamente malo, pero si su código produce un volcado de núcleo, es más fácil hacer una cuenta de error si el archivo de programa incluye información de depuración. El costo principal de la información de depuración es secciones adicionales en el archivo de programa que no necesitan cargarse en la memoria del sistema: el costo del tiempo de ejecución es pequeño.
    • Debería considerar incluir indicadores de optimización allí. Con el conjunto de herramientas GCC, puede usar -g y -O. Es más difícil depurar código optimizado, pero le brinda beneficios de rendimiento (a menudo significativos).
+0

"Si hay un error, es que podría terminar vinculando archivos de objetos creados en modo de depuración para crear la compilación final". No estoy claro con esa declaración. Antes de crear la versión de lanzamiento, limpiaré todos los archivos de objeto existentes y realizaré una versión de lanzamiento. Para que tenga los archivos correctos de lanzamiento vinculados. ¿Eso esta bien? Gracias por la respuesta. –

+0

Supongamos que ejecuta 'make', luego edita un archivo fuente y luego ejecuta 'make mode = release'; la mayoría de los archivos de objeto se compilaron en modo de depuración, aunque es una compilación de 'lanzamiento'. Si, como sugieres, haces 'make mode = release clean all', entonces deberías estar bien. Es por eso que no dije "Es un defecto"; Indiqué que es un problema posible a tener en cuenta. (Además, no hay una solución simple: necesita un rastreador de compilación más sofisticado que registre cómo se crearon los archivos del objeto, incluidas las opciones del compilador. Consulte 'ccache' http://ccache.samba.org/ para ver un ejemplo). –

11

Yo sugeriría siguientes modos:

for debugger: -O0 -g -Wall 
for development and internal release: -O2 -g -Wall 
for release outside the company: -O2 -Wall 

Justificación:

  • Es muy importante desarrollar y probar el código en el "modo de producción".Puede encontrar que en algunos casos el código que funciona sin optimización se bloquea en modo optimizado porque del error en su código. (Créanme que esto sucede mucho) - Así que use -O2
  • En la mayoría de los casos, todavía puede depurar bastante bien incluso con código optimizado, así que agregue -g. Sin embargo, si esto es demasiado difícil de encontrar el error en dicho modo, puede compilar para el depurador con -O0
  • Solo si tiene problemas, incluida la información de depuración en el código, debe eliminar -g. Es una buena idea tener -g para el código en el entorno de producción, porque si algo falla puede obtener mucha más información.
3

Me gustaría tomar el consejo de Artyom sobre las banderas y hacer uso de -O.

Mi principal consejo es hacer que el modo predeterminado sea "liberar". Ningún usuario que no pertenezca a su empresa conocerá su convención make mode=release y el 99.99% de ellos querrá que se cree para su lanzamiento.

Me gusta que tenga -Wall en todos los modos. Si quieres ponerte realmente pedante ... -Wall -std=c++98 -pedantic -Wextra -Wconversion es un buen comienzo. -std = C++ 98 puede no ser necesario si está casado con g ++, pero si tiene alguna ilusión de portabilidad, querrá eso.

Cuestiones relacionadas