未在makefile中追加CXXFLAGS

未在makefile中追加CXXFLAGS,makefile,gnu-make,Makefile,Gnu Make,我有一个makefile,我希望能够生成发布版本和调试版本。当我刚刚跑步时: make 我希望CXXFLAGS是: -std=c++11 -Isrc/includes -c -Os 当我跑的时候 make debug 我希望CXXFLAGS是 -std=c++11 -Isrc/includes -c -g 我试图通过使用虚假目标并向CXXFLAGS变量附加额外标志来实现这一点,但是这些额外标志永远不会被附加。为什么make debug仍然会产生: g++ -std=c++11 -Isr

我有一个makefile,我希望能够生成发布版本和调试版本。当我刚刚跑步时:

make 
我希望CXXFLAGS是:

-std=c++11 -Isrc/includes -c -Os
当我跑的时候

make debug
我希望CXXFLAGS是

-std=c++11 -Isrc/includes -c -g
我试图通过使用虚假目标并向CXXFLAGS变量附加额外标志来实现这一点,但是这些额外标志永远不会被附加。为什么make debug仍然会产生:

g++ -std=c++11 -Isrc/includes -c  src/file.cpp -o build/obj/file.o
而不是预期的

g++ -std=c++11 -Isrc/includes -c -g src/file.cpp -o build/obj/file.o
什么时候运行

makefile的内容:

vpath %.cpp src/macro
vpath %.cpp src/data_types
vpath %.hpp src/includes
vpath %.cpp src

CXX := g++
CXXFLAGS := -std=c++11 -Isrc/includes -c 
LXX = g++
LXXFLAGS := 

BUILDDIR := build
OBJDIR := $(BUILDDIR)/obj

SRCS := $(notdir $(shell find -name '*.cpp'))
OBJS := $(patsubst %.cpp, $(OBJDIR)/%.o, $(SRCS))

all: release aval

aval: builddir $(OBJS) $(SRCS) 
    $(LXX) $(LXXFLAGS) $(OBJS) -o $(BUILDDIR)/aval

$(OBJDIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) $^ -o $@

.PHONY: release
release: CXXFLAGS += -Os
release: LXXFLAGS += -s -Os

.PHONY: debug
debug:  clean db aval

.PHONY: db
db: CXXFLAGS += -g 


.PHONY: builddir
builddir:
    @mkdir -p $(OBJDIR)

.PHONY: clean
clean:
    @rm -f -r build/obj/*.o
    @rm -f build/avalanche

您选择的方法不起作用,因为

db:cxflags+=-g
表示变量
cxflags
已更新,以包括目标
db
-g
,但不包括其他目标。也就是说,这一变化并不像您预期的那样是全球性的


以下是实现您的计划的一种方法:

.PHONY:全部发布
#注意:必须是Makefile中的第一个目标才能成为默认目标
所有版本:
$(MAKE)-f$(lastword$(MAKEFILE_LIST))BUILD\u cxflags=“-Os”BUILD\u lxflags=“-s-Os”BUILD
.假的:调试
调试:
$(MAKE)-f$(lastword$(MAKEFILE_LIST))BUILD\u cxflags=“-g”BUILD\u lxflags=“-g”BUILD
.伪造:建造
建造:清洁雪崩
CXX:=g++
CXXFLAGS:=$(构建\u CxFlags)-std=c++11-Isrc/includes-c
LXX=g++
LXXFLAGS:=$(构建LxFlags)
# ... 以及原始生成文件的其余部分。。。
通过将
build
实现为虚拟回显,我从上面得到以下输出:

$make-s
CXX'-Os-std=c++11-Isrc/包括-c'LXX'-s-Os'
$make-s全部
CXX'-Os-std=c++11-Isrc/包括-c'LXX'-s-Os'
$make-s发布
CXX'-Os-std=c++11-Isrc/包括-c'LXX'-s-Os'
$make-s调试
CXX'-g-std=c++11-Isrc/includes-c'LXX'-g'

顺便说一句:您还需要将
-g
添加到
LXXFLAGS
,否则您将无法获得调试二进制文件。

您所做的问题是,您正在编辑规则的依赖项列表中的CXXFLAGS,但由于make文件的解析方式,该规则无法工作

另一种方法——非常简单,避免了你反复调用make——我不认为这是特别邪恶的——但有些确实如此。我发现这样肯定不那么复杂

CXXFLAGS = defaults

ifneq (,$(findstring release,$(MAKECMDGOALS)))
  CXXFLAGS += release
else ifneq (,$(findstring debug,$(MAKECMDGOALS)))
  CXXFLAGS += debug
endif

all:
    @echo CXXFLAGS = $(CXXFLAGS)

# Rules for release / debug. The `; @:` part means the body of the rule is empty (do nothing). It just "calls" the dependency rule `all`.
release: all ; @:
debug: all ; @:
因此,这里我们将查看命令目标并“解析它们”,以查找您的选项并添加到标志中

我们还需要调试和发布规则来调用构建规则(我现在调用
all

以下是输出:

admin@osboxes:~/sandbox/flags$ make
    CXXFLAGS = defaults
admin@osboxes:~/sandbox/flags$ make release
    CXXFLAGS = defaults release
admin@osboxes:~/sandbox/flags$ make debug
    CXXFLAGS = defaults debug

db:cxflags+=-g
表示变量
cxflags
针对目标
db
进行了更新,但没有其他目标,也就是说,没有以正确的方式进行“全局”更新,而且它似乎不起作用。在构建中,我有@echo$(cxflags),当我运行make-s调试程序时,它会输出-std=c++11-Isrc/includes-c。我发现这是因为在lxflags上设置了-g,这很有意义。对不起,我刚才注意到我的答案中有一个输入错误。固定的。