编写生成文件以在调试构建中使用 -D_GLIBCXX_DEBUG

Posted

技术标签:

【中文标题】编写生成文件以在调试构建中使用 -D_GLIBCXX_DEBUG【英文标题】:Writing a makefile to use -D_GLIBCXX_DEBUG in debug build 【发布时间】:2011-12-10 02:46:52 【问题描述】:

我有一个 makefile 可以简化为:

OBJS = obj1.o obj2.o

FLAGS = -Wall -Wextra -Werror -pedantic-errors -fno-rtti -std=c++0x
DEBUG_FLAGS = -ggdb -O0 -fstack-protector-all -D_GLIBCXX_DEBUG
RELEASE_FLAGS = -O3

release: $(OBJS)
    g++ $(FLAGS) $(RELEASE_FLAGS) $(OBJS)

debug: $(OBJS)
    g++ $(FLAGS) $(DEBUG_FLAGS) $(OBJS)

obj1.o: obj1.cpp
    g++ -c $(FLAGS) obj1.cpp

obj2.o: obj2.cpp
    g++ -c $(FLAGS) obj2.cpp

问题是所有文件或所有文件都必须使用-D_GLIBCXX_DEBUG 标志构建。如果不为每个编译单元编写两个条目,我不知道该怎么做,比如

obj1_release.o: obj1.cpp
    g++ -c $(FLAGS) $(RELEASE_FLAGS) obj1.cpp

obj1_debug.o: obj1.cpp
    g++ -c $(FLAGS) $(DEBUG_FLAGS) obj1.cpp

如何使-D_GLIBCXX_DEBUG 标志(和其他调试标志)仅在用户键入make debug 而不为每个CU 编写两个条目时对所有编译单元生效? (反之亦然;当用户键入make release时,释放标志需要在所有CU上生效。)

如果这是编写 Makefile 的基础知识,我深表歉意,我对它们了解不多。

【问题讨论】:

您不需要在定义 Make 变量的行上使用这些美元符号。 @Zack 哎呀,我打错了。 【参考方案1】:

您正在寻找pattern rules:这样的事情应该可以满足您的需求。请注意,除非程序的调试和发布版本被赋予不同的名称,否则此无法正常工作。

OBJS   := obj1 obj2 obj3
R_OBJS := $(OBJS:=_r.o)
D_OBJS := $(OBJS:=_d.o)

all: prog_r prog_d
release: prog_r
debug: prog_d

prog_r: $(R_OBJS)
    $(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(LDFLAGS) $^ $(LIBS) -o $@

prog_d: $(D_OBJS)
    $(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(LDFLAGS) $^ $(LIBS) -o $@

%_r.o: %.cc
    $(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) -c $< -o $@

%_d.o: %.cc
    $(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) -c $< -o $@

# header files
obj1_d.o obj1_r.o: foo.h bar.h
obj2_d.o obj2_r.o: quux.h
# ... etc ...

【讨论】:

D_OBJS := $(OBJS:-_d.o) 应该是D_OBJS := $(OBJS:=_d.o),还是- 应该只存在于D_OBJS 而不是R_OBJS 打错字了;在这两种情况下都应该是=。会修复的。 那么你如何为每个.cc文件做依赖呢?例如,我有一些 .cc 文件依赖的头文件,而有些则不依赖这些头文件。我将它们标记为使用它们的文件的依赖项,以便在修改标头时重新编译它们,但它们不是不使用它们的文件的依赖项。似乎这种方法使所有 .cc 文件具有完全相同的先决条件(即它正在编译的 .cc 文件),还是我遗漏了什么? 这些是.o 文件的正确依赖项,而不是.cc 文件(您不必在更改标题时重新生成源代码,嗯?) 你可以在没有命令的规则中列出它们,模式规则仍然适用。我将添加一个示例。 如果你有十个以上的目标文件,你可能不想手动更新头文件的依赖关系——在这一点上,投资学习automake,这将安排生成它们作为编译的副作用。【参考方案2】:

有一个pretty straightforward way 可以根据 Makefiles 中的构建类型选择编译标志。

除此之外,您可能希望确保调试构建仅链接调试目标文件并且相同的发布(即不混合调试和发布目标文件)。根据构建类型将编译对象实现到不同的目录中。

【讨论】:

【参考方案3】:

这可能会有所帮助:http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_7.html

您可以检查第一个参数(调试/发布)并相应地设置 CFLAGS。

HTH。

【讨论】:

以上是关于编写生成文件以在调试构建中使用 -D_GLIBCXX_DEBUG的主要内容,如果未能解决你的问题,请参考以下文章

如何生成 iPhone 模拟器构建或 .zip 文件以在 Facebook 中提交以在 iOS 中进行审核

编写 Python 脚本以在 lldb 中打印出一个 recs 数组

如何从 InvokeProcess 活动中获取构建配置(“发布”、“调试”)

EMFile:打开的文件太多,观看 - 构建 Release 反应原生 iOS 应用程序

如何安全地存储 .pfx 密码以在 MSBuild 中使用?

创建 mdb 文件以在 Unity 中调试托管 DLL