带有发布和调试版本的简单makefile - 最佳实践

Nav*_*K N 23 c++ makefile g++

我是makefiles的新手.我从"使用GNU make管理项目"一书中学习了makefile创建和其他相关概念.makefile现在准备好了,我需要确保我创建的那个是好的.这是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
Run Code Online (Sandbox Code Playgroud)

问题

  1. 上面给出的makefile适用于发布和调试版本.但它的格式是否正确?或者你看到有什么缺陷吗?
  2. 在使用make调用时,makefile上面默认调试构建.对于发布版本,需要make mode = release.这是正确的方法吗?
  3. 提供给g ++的调试和发布编译器标志是否正确?对于调试,我使用-g -Wall和发布,只使用-Wall.这是正确的吗?

任何帮助都会很棒.

Jon*_*ler 13

  1. 这是一种合理的格式.它与GNU Make特别相关,但如果您选择在每个平台上使用GNU Make,那么这是一个相对较小的问题.
    • 如果存在缺陷,那么您最终可能会链接在调试模式下构建的目标文件以创建最终构建.
    • 有些人可能认为'mode = release'选项是非标准的; 他们是对的,但我没有一个标准的选择.你只需要知道你的约定可能不适合每个人(但它没有 - 它只需要适合你和你的用户).
  2. 默认情况下构建调试版本可能是明智的 - 并且比默认构建版本构建更明智.
  3. 删除-g发布版本的标志不会自动坏,但如果您的代码产生核心转储,如果程序文件包含调试信息,则更容易构成核心转储的头部或尾部.调试信息的主要成本是程序文件中不需要加载到系统内存中的额外部分 - 运行时成本很小.
    • 您应该考虑是否在其中包含优化标志.使用GCC工具集,您可以使用-g-O.调试优化代码更加困难,但它为您提供(通常很重要的)性能优势.


Art*_*yom 11

我会建议以下模式:

for debugger: -O0 -g -Wall
for development and internal release: -O2 -g -Wall
for release outside the company: -O2 -Wall
Run Code Online (Sandbox Code Playgroud)

理由:

  • 在"生产模式"中开发和测试代码非常重要.在某些情况下,由于代码中的错误,您可以在优化模式下找到无优化崩溃的代码.(相信我,这发生了很多) - 所以使用-O2
  • 在大多数情况下,即使使用优化代码,您仍然可以很好地调试,因此请添加-g.但是,如果在这种模式下很难找到bug,你可以编译调试器-O0
  • 只有在代码中包含调试信息的问题时,才应删除-g.-g在生产环境中使用代码是个好主意,因为如果某些内容崩溃,您可以获得更多信息.