c++ - mac - Makefile simple con compilaciones de lanzamiento y depuración-Mejores prácticas
g++ mac (3)
Soy nuevo en makefiles. Aprendí la creación de makefile y otros conceptos relacionados del libro "Gestionar proyectos con GNU make". El archivo make está ahora listo y necesito asegurarme de que el que creé esté bien. Aquí está el makefile
#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 $@
depend:
makedepend -- $(DFLAGS) -- $(SRC)
.PHONY:clean
clean:
find . -name "*.o" | xargs rm -vf
rm -vf fooexe
Preguntas
- El archivo makefile dado anteriormente funciona bien con las versiones de lanzamiento y depuración. ¿Pero está en el formato correcto? ¿O ves algún defecto en eso?
- Por encima de makefile se realiza la depuración de la compilación de forma predeterminada cuando se invoca con make . Para compilaciones de lanzamiento, make mode = release es obligatorio. ¿Es este el enfoque correcto?
- ¿Los indicadores de compilación de debug y release suministrados a g ++ son correctos? Para la depuración, uso -g -Wall y para lanzar, solo -Wall . ¿Es esto correcto?
Cualquier ayuda sería genial.
- 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 defecto, es que podría terminar vinculando archivos de objetos integrados en el modo de depuración para crear la compilación final.
- Algunos podrían argumentar que una opción ''modo = liberación'' no es estándar; tendrían razón, pero no hay una alternativa estándar que yo sepa. Solo debe tener en cuenta que su convención puede no ser adecuada para todos (pero no es necesario, solo tiene que adaptarse a usted y a sus usuarios).
- La creación de una compilación de depuración por defecto es probablemente sensata, y más sensata que la compilación de la versión por defecto.
- La eliminación del
-g
para la compilación de la versión no es automáticamente mala, pero si su código produce un volcado de núcleo, es más fácil hacer cabecera o cola del volcado de núcleo si el archivo de programa incluye información de depuración. El costo principal de la información de depuración son secciones adicionales en el archivo de programa que no necesitan ser cargadas en la memoria del sistema, el costo de tiempo de ejecución es pequeño.- Debería considerar si incluir indicadores de optimización allí. Con el conjunto de herramientas GCC, puede usar tanto
-g
como-O
. Es más difícil depurar el código optimizado, pero le brinda beneficios (a menudo significativos) de rendimiento.
- Debería considerar si incluir indicadores de optimización allí. Con el conjunto de herramientas GCC, puede usar tanto
Sugeriría los siguientes modos:
for debugger: -O0 -g -Wall
for development and internal release: -O2 -g -Wall
for release outside the company: -O2 -Wall
Razón fundamental:
- Es muy importante desarrollar y probar el código en "modo de producción". Puede encontrar que, en algunos casos, el código que funciona sin optimización se bloquea en modo optimizado debido al error en su código. (Créeme, esto pasa mucho) - Entonces usa
-O2
- En la mayoría de los casos, aún puede depurar bastante bien incluso con código optimizado, así que agregue
-g
. Sin embargo, si esto es demasiado difícil para encontrar el error en tal modo, puede compilar para el depurador con-O0
- Solo si tiene problemas para incluir 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.
Tomaría el consejo de Artyom sobre las banderas y haría uso de -O
.
Mi principal consejo sería hacer el modo predeterminado "release". Ningún usuario ajeno a su empresa sabrá acerca de su convención make mode=release
y el 99,99% de ellos querrá que se cree para el lanzamiento.
Me gusta que tengas -Wall
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.