当我更改Makefile时,它的规则可能已经改变,所以应该重新评估它们,但make似乎并不这么认为.
有没有办法说,在Makefile中,它的所有目标,无论哪个目标,都取决于Makefile本身?(无论其名称如何.)
我正在使用GNU make.
我有一个GNU Makefile(版本3.81),如下所示:
.PHONY: SPOneDot
SPOneDot:
ifndef X
X=0.05
$$(info X undefined, changed to $X)
endif
ifndef Y
Y=0.05
$$(info Y undefined, changed to $Y)
endif
python ./Submit3DSP.py -f OneDot.qdt -x $(X) -y $(Y)
Run Code Online (Sandbox Code Playgroud)
我使用以下命令行执行:make X=0.1 Y=0.1 SPOneDot但是我得到以下结果:
ifndef X
make: ifndef: Command not found
make: *** [SPOneDot] Error 127
Run Code Online (Sandbox Code Playgroud)
我查看了makefile文档,看到其他人使用它.任何帮助表示赞赏,这可能是愚蠢的.
这与Make a Makefile仅在发生错误时执行代码略有不同?.
我想要在发生错误时制定规则或特殊目标(独立于给定目标;不更改每个目标的规则,因为另一个答案似乎暗示了||运算符).
在dmake的有特殊目标 .ERROR即每当检测到错误条件时执行.GNU make有类似的东西吗?
(我还在使用GNU make 3.81,但我在新的GNU make 4.0的文档中找不到任何内容)
我刚刚开始学习移植 Android。我遇到了一种新类型的文件,即 .mk 文件。它是 Makefile 的扩展,但我不知道它与 Makefile 有什么不同?那么,有人可以帮助您澄清它们。非常感谢 !
下面的示例代码中的dep2函数有什么问题?
dep1 = $(eval makefile_list_$1 := $(MAKEFILE_LIST))$(eval -include $1.mk)$(eval MAKEFILE_LIST := $(makefile_list_$1))
define dep2
$(eval makefile_list_$1 := $(MAKEFILE_LIST))
$(eval -include $1.mk)
$(eval MAKEFILE_LIST := $(makefile_list_$1))
endef
$(call dep1,test)
$(call dep2,test)
.DEFAULT_TARGET: all
.PHONY: all
all:
@echo $@
Run Code Online (Sandbox Code Playgroud)
GNU make 3.81和3.82产生Makefile:10: *** missing separator. Stop.指向dep2调用,dep1运行没有错误.两个变体之间的唯一区别是dep2中的换行符(以及我想使用define的全部要点).
我正在尝试编译一组目标.然而它似乎只做第一个.下面是我的makefile的减少,显示错误.
OBJECTS = abc def ghi
SOURCES = abc.c def.c ghi.c
$(OBJECTS): $(SOURCES)
@echo target is $@, source is $<
Run Code Online (Sandbox Code Playgroud)
在壳中,
$ touch abc.c def.c ghi.c
$ make
Run Code Online (Sandbox Code Playgroud)
当我运行make时,我得到以下输出:
target is abc, source is abc.c
Run Code Online (Sandbox Code Playgroud)
所以它似乎只是在运行第一个目标.
如果我用$ ^替换$ <,则输出为:
target is abc, source is abc.c def.c ghi.c
Run Code Online (Sandbox Code Playgroud)
我的问题是,是否可以对变量进行扩展,例如(%:%)模式?
在GNU makefile中,如果输入变量等于两个值中的一个,我想将输出变量设置为一个值(假设为"true"),如果输入变量不等于另一个值("false").
感谢这个SO答案,我已经了解了这些and和or功能,不久之后我就找到了这个if功能.这些函数似乎在我的make版本中可用,所以我想使用它们.我想写这样的东西:
TEST_INPUT = `hostname`
TEST_OUTPUT = $(if $(or $(eq $(TEST_INPUT),hal9000),
$(eq $(TEST_INPUT),pipboy)),true,false)
Run Code Online (Sandbox Code Playgroud)
不幸的是我不能,因为我找不到任何明显形式的预期eq功能.我能够使用该filter功能实现我想要的:
TRUE_HOSTS = hal9000 pipboy
TEST_OUTPUT = $(if $(filter $(TEST_INPUT),$(TRUE_HOSTS)),true,false)
Run Code Online (Sandbox Code Playgroud)
或subst功能:
TEST_OUTPUT = $(if $(and $(subst hal9000,,$(TEST_INPUT)),
$(subst pipboy,,$(TEST_INPUT))),
false,true)
Run Code Online (Sandbox Code Playgroud)
但对我来说,它不是一个漂亮的外观也不是可读的代码.是否有更接近第一个示例的解决方案(使用不存在eq函数的解决方案)?也许我没有达到目的if,and而且or功能完全没有?
我有一个包含一组布尔值的Makefile,必须用它来控制外部应用程序的标志.问题是该标志必须以逗号分隔的字符串形式传递.
像这样的东西(非工作伪代码):
WITH_LIST = ""
WITHOUT_LIST = ""
ifeq ($(BOOL_A),y)
# Append A to list "WITH_LIST"
else
# Append A to list "WITHOUT_LIST"
endif
ifeq ($(BOOL_B),y)
# Append B to list "WITH_LIST"
else
# Append B to list "WITHOUT_LIST"
endif
ifeq ($(BOOL_C),y)
# Append C to list "WITH_LIST"
else
# Append C to list "WITHOUT_LIST"
endif
Run Code Online (Sandbox Code Playgroud)
现在假设BOOL_A == y,BOOL_B == n和BOOL_C == y,我需要运行以下命令:
./app --with=A,C --with-out=B
Run Code Online (Sandbox Code Playgroud)
如何使用Gnu Make生成这些字符串?
在GNU使手动说
有可能不止一个模式规则符合这些标准.在这种情况下,make将选择具有最短词干的规则(即,最具体匹配的模式).
所以它让我感到惊讶:
$ touch make_specific.cpp
$ cat Makefile.general_first
%.o: %.cpp
@echo using general rule
$(CXX) -c $< -o $@
%_specific.o: %_specific.cpp
@echo using specific rule
$(CXX) -c $< -o $@
$ make -B -f Makefile.general_first make_specific.o
using general rule
g++44 -c make_specific.cpp -o make_specific.o
Run Code Online (Sandbox Code Playgroud)
多模式规则匹配目标,并因为对干%_specific.o : %_specific.cpp规则(在这种情况下,"制作")比杆的短%.o : %.cpp规则,我预期的要选择的特定规则,但事实并非如此.
我错过了什么?
我想只为特定目标使用include指令.我不想在不需要目标时运行其他makefile,因为这意味着不必要地生成makefile.
那么有没有办法有条件地使用include指令,它是以目标为条件的?或者以某种方式使include指令成为目标的先决条件.
这是我到目前为止所拥有的:
# Flags
INCDIR = $(CURDIR)/include
CFLAGS = -Wall -Wno-overflow -Wno-uninitialized -pedantic -std=c99 -I$(INCDIR) -O3
LFLAGS = -flat_namespace -dynamiclib -undefined dynamic_lookup
# Directory names
# Set vpath search paths
vpath %.h include
vpath %.c src
vpath %.o build
vpath %.d build
# Get files for the core library
CORE_FILES = $(wildcard src/*.c)
CORE_OBJS = $(patsubst src/%.c, build/%.o, $(CORE_FILES))
CORE_DEPS = $(CORE_OBJS:.o=.d)
# Core library target linking
core : $(CORE_OBJS) | bin
$(CC) $(LFLAGS) -o bin/libcbitcoin.2.0.dylib $(CORE_OBJS)
# Include …Run Code Online (Sandbox Code Playgroud)