C++ 带有发布和调试版本的简单 makefile - 最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/792217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple makefile with release and debug builds - Best practices
提问by Navaneeth K N
I am new to makefiles. I learned makefile creation and other related concepts from "Managing projects with GNU make" book. The makefile is ready now and I need to make sure the one which I created is OK. Here is the makefile
我是 makefile 的新手。我从“使用 GNU make 管理项目”一书中学习了 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
Questions
问题
- The above given makefile works well with release and debug builds. But is it in the correct format? Or do you see any flaws in that?
- Above makefile does debug build by default when invoked using make. For release builds, make mode=releaseis required. Is this the correct approach?
- Is the debug and release compiler flags supplied to g++ is correct? For debug, I use -g -Walland for release, just -Wall. Is this right?
- 上面给出的 makefile 适用于发布和调试版本。但它的格式正确吗?或者你觉得这有什么缺陷?
- 当使用make调用时,上面的 makefile 默认情况下会调试构建。对于发布版本,需要make mode=release。这是正确的方法吗?
- 提供给 g++ 的调试和发布编译器标志是否正确?对于调试,我使用-g -Wall和发布,只是-Wall。这是正确的吗?
Any help would be great.
任何帮助都会很棒。
采纳答案by Jonathan Leffler
- It is one reasonable format. It is tied specifically to GNU Make, but that's a relatively minor problem if you have chosen to use GNU Make on every platform.
- If there is a flaw, it is that you could end up linking object files built in debug mode to create the final build.
- Some might argue that a 'mode=release' option is non-standard; they'd be right, but there isn't a standard alternative that I'm aware of. You just need to be aware that your convention might not suit everyone (but it doesn't have to - it just has to suit you and your users).
- Building a debug build by default is probably sensible - and more sensible than building the release build by default.
- Dropping the
-g
flag for the release build is not automatically bad, but if your code ever produces a core dump, it is easier to make head or tail of the core dump if the program file includes debugging information. The primary cost of debugging information is extra sections in the program file that do not need to be loaded into system memory - the runtime cost is small.- You should consider whether to include optimization flags in there. With the GCC tool set, you can use both
-g
and-O
. It is harder to debug optimized code, but it gives you (often significant) performance benefits.
- You should consider whether to include optimization flags in there. With the GCC tool set, you can use both
- 这是一种合理的格式。它专门与 GNU Make 相关联,但如果您已选择在每个平台上使用 GNU Make,这将是一个相对较小的问题。
- 如果存在缺陷,那就是您最终可以链接在调试模式下构建的目标文件以创建最终版本。
- 有些人可能会争辩说,'mode=release' 选项是非标准的;他们是对的,但没有我所知道的标准替代方案。您只需要知道您的约定可能并不适合所有人(但它不一定适合 - 它只需要适合您和您的用户)。
- 默认情况下构建调试版本可能是明智的 - 并且比默认情况下构建发布版本更明智。
- 删除
-g
发布版本的标志并不一定是坏事,但是如果您的代码曾经产生过核心转储,那么如果程序文件包含调试信息,则更容易制作核心转储的头部或尾部。调试信息的主要成本是程序文件中不需要加载到系统内存中的额外部分——运行时成本很小。- 您应该考虑是否在其中包含优化标志。使用 GCC 工具集,您可以同时使用
-g
和-O
. 调试优化代码比较困难,但它为您提供(通常是显着的)性能优势。
- 您应该考虑是否在其中包含优化标志。使用 GCC 工具集,您可以同时使用
回答by Artyom
I would suggest following modes:
我建议以下模式:
for debugger: -O0 -g -Wall
for development and internal release: -O2 -g -Wall
for release outside the company: -O2 -Wall
Rationale:
理由:
- It is very important to develop and test the code in "production mode". You can find
that in some cases code that works without optimization crashes in optimized mode because
of the bug in your code. (Believe me this happens a lot) -- So use
-O2
- In most of cases you still can debug quite well even with optimized code, so add
-g
. However, if this is too hard to find the bug in such mode you can compile for debugger with-O0
- Only if you have problems including debug information in code, you should remove
-g
. It is good idea to have-g
for the code in production environment, because if something crashes you can get much more information.
- 在“生产模式”下开发和测试代码非常重要。您会发现,在某些情况下,由于您的代码中的错误,无需优化即可运行的代码会在优化模式下崩溃。(相信我这种情况经常发生)——所以使用
-O2
- 在大多数情况下,即使使用优化的代码,您仍然可以很好地调试,因此添加
-g
. 但是,如果在这种模式下很难找到错误,您可以使用以下命令编译调试器-O0
- 只有当您在代码中包含调试信息时遇到问题,您才应该删除
-g
.-g
在生产环境中使用代码是个好主意,因为如果出现崩溃,您可以获得更多信息。
回答by Schwern
I'd take Artyom's advice about the flags and make use of -O
.
我会听取 Artyom 关于标志的建议并使用-O
.
My major piece of advice would be to make the default mode "release". No user outside your company is going to know about your make mode=release
convention and 99.99% of them will want it built for release.
我的主要建议是将默认模式设为“发布”。公司以外的用户不会知道你的make mode=release
约定,他们中的 99.99% 会希望它是为发布而构建的。
I like that you've got -Wall
on in all modes. If you want to get really pedantic... -Wall -std=c++98 -pedantic -Wextra -Wconversion
is a good start. -std=c++98 may not be necessary if you're wedded to g++, but if you have any illusions of portability you'll want that.
我喜欢你-Wall
在所有模式中都表现得很好。如果你想变得真正迂腐......-Wall -std=c++98 -pedantic -Wextra -Wconversion
是一个好的开始。-std=c++98 如果你坚持使用 g++ 可能不是必需的,但如果你对便携性有任何幻想,你会想要它。