Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更改目标主体内的Makefile变量值_Makefile_Target - Fatal编程技术网

更改目标主体内的Makefile变量值

更改目标主体内的Makefile变量值,makefile,target,Makefile,Target,有没有办法在目标主体内部重新分配Makefile变量值 我试图做的是为调试编译添加一些额外的标志: %.erl: %.beam $(ERLC) $(ERLFLAGS) -o ebin $< test: clean debug_compile_flag compile compile_test debug_compile: $(ERLCFLAGS) += -DTEST %.erl:%.beam $(ERLC)$(ERLC)-息税前利润$< 测试:清除调试\u编译\u标志

有没有办法在目标主体内部重新分配Makefile变量值

我试图做的是为调试编译添加一些额外的标志:

%.erl: %.beam
    $(ERLC) $(ERLFLAGS) -o ebin $<

test: clean debug_compile_flag compile compile_test

debug_compile:
    $(ERLCFLAGS) += -DTEST
%.erl:%.beam
$(ERLC)$(ERLC)-息税前利润$<
测试:清除调试\u编译\u标志编译\u测试
调试和编译:
$(ERLCFLAGS)+=-DTEST
因此,如果我调用测试目标,我希望清理我的环境,添加一些新标志(如-DTEST到现有标志),再次编译整个代码(首先是源代码,然后是测试模块)

我不想复制/粘贴带有一些新标志集的编译代码,因为这里和那里有很多逻辑


是否有一些简单的方法来重新定义变量值,以便重用现有代码?

编辑:如中的Beta所述,这是可能的


不,在Makefile中无法执行此操作。但是,您可以在
make
命令行上更改变量的值。如果按照以下方式重写Makefile:

ERLCFLAGS += $(ERLCFLAGSADDED)

%.erl: %.beam
    $(ERLC) $(ERLCFLAGS) -o ebin $<

test: clean compile compile_test

是的,有一种简单的方法可以做到这一点,而且无需重新运行Make。使用:

另一个答案是:

对于懒惰者,可以有如下规则(
FLAG
DEBUG
是我的变量):


我想在makefile中添加一个目标来运行测试,这意味着用一些调试标志重新编译源代码。伊恩的回答是:这是唯一有效的解决方案

下面是我提出的Makefile,它保证了运行
maketests
时的执行顺序:

TARGET     = a.out

CC         = g++
GENERIC_F  = -Wall -Wextra -I. -Idoctest/doctest/

CFLAGS     = -O0 -std=c++11 $(GENERIC_F)
DEBUG_MODE = -DDEBUG

LINKER     = g++
LFLAGS     = $(GENERIC_F) -lm

SRCDIR     = src
OBJDIR     = build
BINDIR     = bin

SOURCES    = $(wildcard $(SRCDIR)/*.cc)
INCLUDES   = $(wildcard $(SRCDIR)/*.h)
OBJECTS    = $(SOURCES:$(SRCDIR)/%.cc=$(OBJDIR)/%.o)
rm         = rm -f

.PHONY: clear_screen tests extend_cflags

$(BINDIR)/$(TARGET): $(OBJECTS) $(INCLUDES)
    $(LINKER) $(OBJECTS) $(LFLAGS) -o $@
    @echo -e "Linking complete!\n"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cc $(INCLUDES)
    @mkdir -p $(OBJDIR) $(BINDIR)
    $(CC) $(CFLAGS) -c $< -o $@
    @echo -e "Compiled "$<" successfully!\n"

.PHONY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

clear_screen:
    @clear

extend_cflags:
    $(eval CFLAGS += $(DEBUG_MODE))

tests: | remove extend_cflags $(BINDIR)/$(TARGET) clear_screen
    @$(BINDIR)/$(TARGET)
TARGET=a.out
CC=g++
GENERIC_F=-Wall-Wextra-I.-Idoctest/doctest/
CFLAGS=-O0-std=c++11$(通用)
调试模式=-DDEBUG
链接器=g++
LFLAGS=$(通用的F)-lm
SRCDIR=src
OBJDIR=build
BINDIR=bin
SOURCES=$(通配符$(SRCDIR)/*.cc)
包括=$(通配符$(SRCDIR)/*.h)
OBJECTS=$(源代码:$(SRCDIR)/%.cc=$(OBJDIR)/%.o)
rm=rm-f
.虚假:清除屏幕测试会扩大空白
$(BINDIR)/$(目标):$(对象)$(包括)
$(链接器)$(对象)$(LFLAGS)-o$@
@echo-e“链接完成!\n”
$(对象):$(OBJDIR)/%.o:$(SRCDIR)/%.cc$(包括)
@mkdir-p$(OBJDIR)$(BINDIR)
$(CC)$(CFLAGS)-c$<-o$@

@echo-e“Compiled”$要在命令行上重写,请尝试以下操作:

make prefix=<path to new dir> install
makeprefix=install

这不会更改Makefile,但会更改变量。

以下是我使用的解决方案:

PASSWORD = abc123

main: sub
    @echo "in main" $(PASSWORD)

sub:
    @echo "in sub" $(PASSWORD)
    $(eval PASSWORD=qwerty)
    @echo "in sub" $(PASSWORD)
如果运行
make main
,则输出为:

in sub abc123
in sub qwerty
in main qwerty

您可以看到原始值
“abc123”
sub
中被覆盖,新值
“qwerty”
main
级别可见。

是的,我按照您的建议解决了问题,在debug\u编译中运行submake:ERLC\u FLAGS=$(ERLC\u debug\u FLAGS)$(MAKE)编译谢谢!哦,是的,太好了。我没有考虑过这个submake调用。如果您想使用不同的标志值多次运行目标,submake调用仍然很有用。见我在下面评论中引用的文件。这里是否保证执行顺序?或者化妆师会把事情搞砸吗“请注意,给定的先决条件每次调用make最多只生成一次。如果同一个文件是多个目标的先决条件,并且这些目标中的每个目标对于同一目标特定变量具有不同的值,则要生成的第一个目标将导致生成该先决条件,并且该先决条件将从第一个目标继承目标特定的值。它将忽略来自任何其他目标的目标特定值。“可能重复的我在
$(eval xxx)
方面有很多问题,有大量奇怪的副作用。它似乎没有“真正的”效果好“Makefile变量赋值。我在
eval
函数中遇到问题-我的变量值为空,因为用eval定义的变量在目标执行开始时获取其值,而不是到达此行时。例如,如果您在目标的开头创建一些文件,然后尝试使用
eval files=$(shell ls)
填充一些变量,那么您的文件变量将在目标旁边为空。我相信您需要$(eval files=$(shell ls)),但我的makefile存在一些问题,这取决于make的版本。更麻烦的是,考虑如果您使用
make a b
,make将抱怨需要使用bar。然后,如果您使用
触摸栏
,则
b
执行中的
echo
将打印
baz
:依赖关系的计算和主体的执行在不同的点进行。让make命令的调用通过在调用时更改变量来决定,这对于简单用例来说是一个很好的解决方案,如提供的示例所示。我想说,对于任何复杂的问题,最好是将其编码,但我喜欢这个解决方案的简单性!
make prefix=<path to new dir> install
PASSWORD = abc123

main: sub
    @echo "in main" $(PASSWORD)

sub:
    @echo "in sub" $(PASSWORD)
    $(eval PASSWORD=qwerty)
    @echo "in sub" $(PASSWORD)
in sub abc123
in sub qwerty
in main qwerty