是优化和生成调试信息的一部分编译或链接

时间:2009-08-21 23:51:05

标签: debugging optimization makefile linker compilation

我正在从其他人那里阅读Makefile,如下所示。

LDFLAGS=-lm -ljpeg -lpng

ifeq ($(DEBUG),yes)
        OPTIMIZE_FLAG = -ggdb3 -DDEBUG -fno-omit-frame-pointer
else
        OPTIMIZE_FLAG = -ggdb3 -O3
endif

CXXFLAGS = -Wall $(OPTIMIZE_FLAG)

all: test

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

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

clean:
        \rm -f test *.o Makefile.depend

-include Makefile.depend

以下是我的问题:

  1. 虽然没有明确说明,但是在编译期间未在此Makefile中显示的隐式规则使用$(CXXFLAGS)来生成目标文件?

  2. 我也想知道为什么$(CXXFLAGS)出现在联动阶段?我认为这仅适用于编译阶段?我可以从“$(CXX)$(CXXFLAGS)-o $ @ $ ^ $(LDFLAGS)”中删除$(CXXFLAGS)吗?如果我错了,是否意味着g ++还会生成调试信息并在链接时进行优化?

  3. 为什么一起使用-ggdb3 -O3进行非调试目的?它的目的是什么?如果仅考虑提高速度,那么不仅仅使用-O3更好吗?

  4. 出于调试目的,如何一起使用-ggdb3 -fno-omit-frame-pointer比单独使用-ggdb3更好?我试图通过阅读gcc文档来理解-fno-omit-frame-pointer的目的,但仍然感到困惑。

  5. 我可以将“-include Makefile.depend”移到“$(CC)-M * .cc> Makefile.depend”和“clean”之上吗?它在Makefile中的位置是否重要?

1 个答案:

答案 0 :(得分:2)

CXXFLAGS由隐式规则使用。请使用-n -p查看Make内部规则集和make文件生成的变量和规则的完整列表。

-g调试选项仅在编译阶段使用。 -O选项可能在编译和链接阶段使用。你可以一起使用。从我的gcc手册页:

  

GCC允许您将-g与-O一起使用。   优化代码采用的快捷方式   可能偶尔会产生令人惊讶的   结果:              您声明的某些变量可能根本不存在;控制流程   可能会暂时移动到你没有的地方   期待它;一些              语句可能无法执行,因为它们计算常量   结果或它们的价值已经存在   在眼前;一些国家 -              因为它们可能会在不同的地方执行   走出了循环。

     

然而,事实证明可以调试优化的输出。   这使得合理使用   可能存在错误的程序的优化器。

-fno-omit-frame-pointer实际上减少了优化。优化可能会干扰调试,并且编写此makefile的人明确打算在优化代码上运行调试器。如果您不清楚gcc手册中的工作原理,您可能希望在某个星期六使用英特尔或AMD架构参考手册,并在指令级别了解函数调用和参数传递。 (然后,也许不是。:))

Makefile中的位置问题。我会在最后留下包含文件。否则可能会破坏包含文件依赖性检查。