如何执行生成规则 return 以构建对象的 makefile 函数
How to do a makefile function that generate rules an return to build objects
我有当前代码
它允许我轻松生成二进制文件的目标文件
define ASSET_RULE
$(addsuffix .o,$(basename $(1))): $(1)
$(LD) -r -b binary $(1) -o $(addsuffix .o,$(basename $(1)))
endef
SRC=avatar.jpg \
avatar2.png
OBJ=$(addsuffix .o,$(basename $(SRC)))
NAME=assets.a
all: $(NAME)
$(foreach file,$(SRC), $(eval $(call ASSET_RULE,$(file))))
$(NAME): $(OBJ)
$(AR) rcs $(NAME) $(OBJ)
clean:
$(RM) $(OBJ)
fclean: clean
$(RM) $(NAME)
re: fclean all
.PHONY: clean fclean all re
我想做一个函数,将资产作为参数,为它们生成规则,然后 return 我将 .o 文件编译为依赖项。
到最后我希望有类似的东西。
ASSETS=avatar.jpg \
avatar2.png
OBJ=$(call BINARY_ASSETS,$(ASSETS))
NAME=assets.a
all: $(NAME)
$(NAME): $(OBJ)
$(AR) rcs $(NAME) $(OBJ)
clean:
$(RM) $(OBJ)
fclean: clean
$(RM) $(NAME)
re: fclean all
.PHONY: clean fclean all re
我试图将 eval 的 foreach 循环与最终对象名称结合起来,但是当我这样做时我得到了 *** prerequisites cannot be defined in recipes.
。
这种事情可以做吗?
OBJ=$(call BINARY_ASSETS,$(ASSETS))
这是错误的,因为 OBJ
的值,即 $(call ...)
,稍后在其他配方和先决条件中被扩展(即调用),这是 make 抱怨的原因。您可以在此处仅使用简单赋值:
OBJ:=$(call BINARY_ASSETS,$(ASSETS))
请参阅 two flavors of variables 上的 make 手册(如果您像我一样发现此文本难以理解,请尝试想象 make 中的“=”运算符将原样的文字字符串赋值给变量)。
此外,我强烈建议尽可能使用自动变量,例如:
$(NAME): $(OBJ)
$(AR) $(ARFLAGS) $@ $?
您需要更新 ASSET_RULE
内的 OBJS
,因为宏将只能 return $(eval)
的 makefile 代码。我已经从您的 makefile 中删除了与当前问题无关的所有部分:
# $(1): source file name
define ASSET_RULE
_obj_name := $(addsuffix .o,$(basename $(1)))
$$(_obj_name): $(1)
$(LD) -r -b binary $$< -o $$@
OBJS += $$(_obj_name)
_obj_name :=
endef
# $(1): list of source files
BINARY_ASSETS = $(eval \
$(foreach _a,$(1), \
$(call ASSET_RULE,$(_a)) \
) \
)
ASSETS := \
avatar.jpg \
avatar2.png
OBJS :=
$(call BINARY_ASSETS,$(ASSETS))
.PHONY: all
all: $(OBJS)
测试 运行 我将 eval
替换为 info
以显示生成的代码:
$ make
_obj_name := avatar.o
$(_obj_name): avatar.jpg
ld -r -b binary $< -o $@
OBJS += $(_obj_name)
_obj_name :=
_obj_name := avatar2.o
$(_obj_name): avatar2.png
ld -r -b binary $< -o $@
OBJS += $(_obj_name)
_obj_name :=
make: Nothing to be done for 'all'.
如果你想用BINARY_ASSETS
更新不同的变量,那么你需要第二个参数来传入变量名:
# $(1): source file name
# $(2): variable name to add object file name to
define ASSET_RULE
_obj_name := $(addsuffix .o,$(basename $(1)))
$$(_obj_name): $(1)
$(LD) -r -b binary $$< -o $$@
$(2) += $$(_obj_name)
_obj_name :=
endef
# $(1): list of source files
# $(2): variable name to add object file names to
BINARY_ASSETS = $(eval \
$(foreach _a,$(1), \
$(call ASSET_RULE,$(_a),$(2)) \
) \
)
$(call BINARY_ASSETS,$(ASSETS),OBJS)
我有当前代码 它允许我轻松生成二进制文件的目标文件
define ASSET_RULE
$(addsuffix .o,$(basename $(1))): $(1)
$(LD) -r -b binary $(1) -o $(addsuffix .o,$(basename $(1)))
endef
SRC=avatar.jpg \
avatar2.png
OBJ=$(addsuffix .o,$(basename $(SRC)))
NAME=assets.a
all: $(NAME)
$(foreach file,$(SRC), $(eval $(call ASSET_RULE,$(file))))
$(NAME): $(OBJ)
$(AR) rcs $(NAME) $(OBJ)
clean:
$(RM) $(OBJ)
fclean: clean
$(RM) $(NAME)
re: fclean all
.PHONY: clean fclean all re
我想做一个函数,将资产作为参数,为它们生成规则,然后 return 我将 .o 文件编译为依赖项。 到最后我希望有类似的东西。
ASSETS=avatar.jpg \
avatar2.png
OBJ=$(call BINARY_ASSETS,$(ASSETS))
NAME=assets.a
all: $(NAME)
$(NAME): $(OBJ)
$(AR) rcs $(NAME) $(OBJ)
clean:
$(RM) $(OBJ)
fclean: clean
$(RM) $(NAME)
re: fclean all
.PHONY: clean fclean all re
我试图将 eval 的 foreach 循环与最终对象名称结合起来,但是当我这样做时我得到了 *** prerequisites cannot be defined in recipes.
。
这种事情可以做吗?
OBJ=$(call BINARY_ASSETS,$(ASSETS))
这是错误的,因为 OBJ
的值,即 $(call ...)
,稍后在其他配方和先决条件中被扩展(即调用),这是 make 抱怨的原因。您可以在此处仅使用简单赋值:
OBJ:=$(call BINARY_ASSETS,$(ASSETS))
请参阅 two flavors of variables 上的 make 手册(如果您像我一样发现此文本难以理解,请尝试想象 make 中的“=”运算符将原样的文字字符串赋值给变量)。
此外,我强烈建议尽可能使用自动变量,例如:
$(NAME): $(OBJ)
$(AR) $(ARFLAGS) $@ $?
您需要更新 ASSET_RULE
内的 OBJS
,因为宏将只能 return $(eval)
的 makefile 代码。我已经从您的 makefile 中删除了与当前问题无关的所有部分:
# $(1): source file name
define ASSET_RULE
_obj_name := $(addsuffix .o,$(basename $(1)))
$$(_obj_name): $(1)
$(LD) -r -b binary $$< -o $$@
OBJS += $$(_obj_name)
_obj_name :=
endef
# $(1): list of source files
BINARY_ASSETS = $(eval \
$(foreach _a,$(1), \
$(call ASSET_RULE,$(_a)) \
) \
)
ASSETS := \
avatar.jpg \
avatar2.png
OBJS :=
$(call BINARY_ASSETS,$(ASSETS))
.PHONY: all
all: $(OBJS)
测试 运行 我将 eval
替换为 info
以显示生成的代码:
$ make
_obj_name := avatar.o
$(_obj_name): avatar.jpg
ld -r -b binary $< -o $@
OBJS += $(_obj_name)
_obj_name :=
_obj_name := avatar2.o
$(_obj_name): avatar2.png
ld -r -b binary $< -o $@
OBJS += $(_obj_name)
_obj_name :=
make: Nothing to be done for 'all'.
如果你想用BINARY_ASSETS
更新不同的变量,那么你需要第二个参数来传入变量名:
# $(1): source file name
# $(2): variable name to add object file name to
define ASSET_RULE
_obj_name := $(addsuffix .o,$(basename $(1)))
$$(_obj_name): $(1)
$(LD) -r -b binary $$< -o $$@
$(2) += $$(_obj_name)
_obj_name :=
endef
# $(1): list of source files
# $(2): variable name to add object file names to
BINARY_ASSETS = $(eval \
$(foreach _a,$(1), \
$(call ASSET_RULE,$(_a),$(2)) \
) \
)
$(call BINARY_ASSETS,$(ASSETS),OBJS)