C++ Makefile 似乎没有应用 `g++` 优化标志

问题描述 投票:0回答:1

我一直在使用下面传给我的 Makefile 来编译 C++ 代码。

CXX := g++-11

CXXFLAGS := -std=c++20 -D_FILE_OFFSET_BITS=64 -fopenmp -Wall -Wextra -Wpedantic -Wold-style-cast -Wshadow -Wcast-qual -Wwrite-strings -Wdisabled-optimization -Wfloat-equal -Wformat=2 -Wformat-overflow -Wformat-truncation -Wundef -fno-common -Wconversion -fdiagnostics-show-option -fdiagnostics-color=auto -Wuninitialized -Wno-unused-function -fstrict-aliasing -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Wno-unused -Wno-unused-result -Wno-unused-parameter -Wcast-align -Wnon-virtual-dtor -Woverloaded-virtual -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wuseless-cast -Wdouble-promotion
CXXFLAGS += -MMD -MP

LDFLAGS := -L
LDLIBS := -lm -lrt -lpthread

SANITIZER := -fsanitize=address,leak,undefined
CXXDEBUG := -g -fno-omit-frame-pointer -fanalyzer -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
CXXRELEASE := -DNDEBUG -O2

MAKEFLAGS := -j

SRC := $(wildcard *.cpp)
OBJ := $(SRC:.cpp=.o)
DEP := $(SRC:.cpp=.d)
DEBUG := $(SRC:.cpp=.dbg)
RELEASE := $(SRC:.cpp=.rel)

.PHONY: all clean

all: $(DEBUG) $(RELEASE)

ifneq ($(MAKECMDGOALS), clean, install) # don't create .d for clean and install goals
-include $(DEP)
endif

%.dbg:%.o
    $(CXX) $(CXXFLAGS) $(CXXDEBUG) $(SANITIZER) $< -o $@ $(LDFLAGS) $(LDLIBS)

%.rel:%.o
    $(CXX) $(CXXFLAGS) $(CXXRELEASE) $< -o $@ $(LDFLAGS) $(LDLIBS)

clean:
    $(RM) $(OBJ) $(DEP) $(RELEASE) $(DEBUG) *~ *.out *.dbg *.rel compile_commands.json *.d

Makefile 似乎会自动扫描所有修改过的 .

cpp
文件,并将每个文件分别编译为文件类型为
.dbg
.rel
的调试版本和发布版本。 但是,我最近注意到
-O2
g++-11 -std=c++20 -O2 main.cpp` 中的优化标志
CXXRELEASE seems to not be applied to the release build. I found this out when I realized that compiling the code through just the command 
生成的可执行文件比 .rel 生成的快一个数量级制作。

谁能找出这个 Makefile 有什么问题吗?我现在很困惑,因为我已经使用这个很多年了,直到我意识到或注意到这个问题 几天前。

c++ makefile compilation c++20
1个回答
0
投票

我一直在使用下面传给我的 Makefile 来编译 C++ 代码。

[...]

我现在很困惑,因为我已经使用这个多年了,直到几天前我才意识到或注意到这个问题。

让这成为一个关于了解工具的必要性的警示故事。

谁能找出这个 Makefile 有什么问题吗?

通常,几乎所有的优化都是在从源文件到目标文件的编译过程中进行的。此 makefile 不为构建的此阶段提供任何优化选项。此外,它使用相同的目标文件来支持

.dbg
可执行文件,就像支持
.rel
可执行文件一样,只要这样做,这些可执行文件彼此之间有意义的不同的空间就有限。

您可以想象构建单独的调试和发布目标文件,后者具有所需的优化。但是,鉴于 makefile 仅构建整个源代码位于单个文件中的程序,因此完全跳过

.o
文件并直接从源代码构建为可执行文件会更容易。如果该文件的任何过去版本成功地完成了它似乎想要做的事情,那么它可能就是这样做的。

返回(返回)此类版本的主要更改是更改

%.dbg
%.rel
规则的先决条件:

%.dbg: %.cpp
        # ...

%.rel: %.cpp
        # ...

由于您将不再构建目标文件,因此您可能还应该从要清理的文件列表中删除

$(OBJ)
,并且可能根本不定义该变量。

© www.soinside.com 2019 - 2024. All rights reserved.