【问题标题】:optimization and debugging options in MakefileMakefile 中的优化和调试选项
【发布时间】:2009-08-27 15:42:48
【问题描述】:

我想知道Makefile中的优化和调试选项放在哪里:链接阶段还是编译阶段?我正在阅读 Makefile:

ifeq ($(STATIC),yes)
  LDFLAGS=-static -lm -ljpeg -lpng -lz
else
  LDFLAGS=-lm -ljpeg -lpng
endif

ifeq ($(DEBUG),yes)
  OPTIMIZE_FLAG = -ggdb3 -DDEBUG
else
  OPTIMIZE_FLAG = -ggdb3 -O3
endif

ifeq ($(PROFILE),yes)
  PROFILE_FLAG = -pg
endif

CXXFLAGS = -Wall $(OPTIMIZE_FLAG) $(PROFILE_FLAG) $(CXXGLPK)

test: test.o rgb_image.o 
    $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

Makefile.depend: *.h *.cc Makefile
    $(CC) -M *.cc > Makefile.depend

clean:
    \rm -f absurdity *.o Makefile.depend TAGS

-include Makefile.depend

让我惊讶的是 CXXFLAGS 用于链接。我知道它也用于编译生成 .o 文件的隐式规则中,但是否有必要再次使用它进行链接?具体来说,我应该把优化和调试放在哪里:链接阶段还是编译阶段?

【问题讨论】:

  • 请注意,代码格式(使用反引号或四个空格缩进)与使用“>”的块引号不同。

标签: debugging optimization makefile linker compilation


【解决方案1】:

简答:

  • 优化:编译时需要

  • 调试标志:在编译时需要

  • 调试符号:在编译和链接时都需要

请注意,链接器决定每个目标文件和库的哪些位需要包含在最终可执行文件中。它可能抛出调试符号(我不知道默认行为是什么),所以你需要告诉它不要。

此外,链接器会默默地忽略不适用于它的选项。


致cmets:

以上是非常笼统的说法,基于知道编译的每个阶段会发生什么,所以没有参考。

更多细节:

  • 优化: 有两种主要形式:窥孔优化可能发生得非常晚,因为它一次只处理几条汇编指令(我假设在GNU 工具链,汇编器负责这一步),但最大的收获是结构优化,通常通过重写抽象语法树 (AST) 来完成,这只能在编译期间实现。

  • 调试标志:在您的示例中,这是一个 预处理器 指令,仅影响编译过程的第一部分。

  • 调试符号:查找 the ELF file format(例如),您会看到各种代码和数据位被组织到不同的块中。调试符号与它们相关的代码一起存储在同一个文件中,但必须与实际代码分开。因此,任何操作这些文件的程序都可以转储它。因此编译器和链接器都需要知道你是否想要它们。

【讨论】:

  • 那么在链接和编译中始终指定 CXXFLAGS 是否更好?
  • 非常感谢!你对“哪件事在哪个阶段完成”有一些参考吗?关于“链接器可能会抛出调试符号”,您的意思是在调试的情况下将 -fno-omit-frame-pointer 添加到 CXXFLAGS 吗?不是用 -g 或 -O0 自动设置的吗?
猜你喜欢
  • 2012-09-05
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2012-01-29
  • 2014-11-24
  • 1970-01-01
相关资源
最近更新 更多