如何执行生成规则以返回构建对象的生成文件函数



>我有当前的代码它使我可以轻松地生成二进制文件的对象文件

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

我想做一个函数,将资产作为参数,为它们生成规则,并将 .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

我试图将我的 foreach 循环与最终的对象名称结合起来,但是当我这样做时,我得到了*** prerequisites cannot be defined in recipes.。这种事情可以做吗?

您需要

ASSET_RULE中更新OBJS,因为宏只能返回$(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)

测试运行,我用info替换了eval以显示生成的代码:

$ 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)
OBJ=$(call BINARY_ASSETS,$(ASSETS))

这是错误的,因为OBJ的价值,即 $(call ...) ,稍后在其他配方和先决条件中扩展(即调用(,这是 make 抱怨的原因。您只能在此处使用简单的赋值:

OBJ:=$(call BINARY_ASSETS,$(ASSETS))

查阅 make 关于两种变量的手册(如果您像我一样发现这段文字难以理解,请尝试想象 make 中的"="运算符将文本字符串原封不动地分配给变量(。

此外,我强烈建议尽可能使用自动变量,例如:

$(NAME): $(OBJ)
    $(AR) $(ARFLAGS) $@ $?

最新更新