C 如何将make变量设置为目标相关值?

C 如何将make变量设置为目标相关值?,c,linux,makefile,C,Linux,Makefile,我不是制造专家,所以如果这是一个愚蠢的问题,我道歉。我想将make变量设置为目标的一部分,这样在target1中它的值是-DPARENT,在target2中它的值是-DCHILD。我有一些通用规则,当检查这些目标的依赖关系时会遵守这些规则,我需要适当地设置这些定义以传递给gcc 这就是我想做的: $(OBJ)/%.o: $(XML)/%.c $(CC) $(CFLAGS) $(XML_BUILD_TYPE) -c -o $@ $< $(PROD)/Parent: \

我不是制造专家,所以如果这是一个愚蠢的问题,我道歉。我想将make变量设置为目标的一部分,这样在target1中它的值是-DPARENT,在target2中它的值是-DCHILD。我有一些通用规则,当检查这些目标的依赖关系时会遵守这些规则,我需要适当地设置这些定义以传递给gcc

这就是我想做的:

$(OBJ)/%.o: $(XML)/%.c
    $(CC) $(CFLAGS) $(XML_BUILD_TYPE) -c -o $@  $<

$(PROD)/Parent: \
        somehow set XML_BUILD_TYPE = -DPARENT here \
        $(XML)/Xml.h \
        $(TOOLS_OBJS) \
        $(XML_PARENT_OBJECTS) \
        $(XML_INPUTS)
    $(CC) -o $@ $(TOOLS_OBJS) $(XML_PARENT_OBJECTS) -rdynamic $(JSON_LIB) $(CURL_LIB) $(LIBS) -lssl -lidn

$(PROD)/Child: \
        somehow set XML_BUILD_TYPE = -DCHILD here \
        $(XML)/Xmlr.h \
        $(TOOLS_OBJS) \
        $(XML_CHILD_OBJECTS) \
    $(CC) $(CFLAGS) -c -o $(OBJ)/LinkDate.o  $(TOOLS)/LinkDate.c
    $(CC) -o $@ $(TOOLS_OBJS) $(XML_CHILD_OBJECTS) -rdynamic $(OBJ)/LinkDate.o $(JSON_LIB) $(CURL_LIB) $(LIBS) -lssl -lidn
$(OBJ)/%.o:$(XML)/%.c
$(CC)$(CFLAGS)$(XML\u BUILD\u TYPE)-c-o$@$<
$(产品)/父项:\
以某种方式在此处设置XML\u BUILD\u TYPE=-DPARENT\
$(XML)/XML.h\
$(工具)\
$(XML\u父对象)\
$(XML_输入)
$(CC)-o$@$(工具\u对象)$(XML\u父对象)-RDDynamic$(JSON\u库)$(CURL\u库)$(库)-lssl-lidn
$(产品)/儿童:\
在这里设置XML\u BUILD\u TYPE=-DCHILD\
$(XML)/Xmlr.h\
$(工具)\
$(XML\u子对象)\
$(CC)$(CFLAGS)-c-o$(OBJ)/LinkDate.o$(工具)/LinkDate.c
$(CC)-o$@$(工具\u对象)$(XML\u子对象)-rdynamic$(OBJ)/LinkDate.o$(JSON\u LIB)$(CURL\u LIB)$(LIBS)-lssl-lidn
我尝试了
$(eval XML\u BUILD\u TYPE:=-DCHILD)
但发现make在读取makefile时会对所有eval进行求值,从而始终设置最后设置的值。我相信这一定是有可能的,但如果我能找到办法的话,我会大发雷霆


感谢您的帮助

可能有一个我不知道的好方法,但在有人发布之前。。。这是我以前解决这类问题的方法

$(PROD)/Parent:
        make XML_BUILD_TYPE=-DPARENT Parent_Build

Parent_Build:
        # put in build steps for the parent; $(XML_BUILD_TYPE) is already set
对于这种策略,您永远不会自己从命令行调用“makeparent\ubuild”;您只需允许make在内部调用它就可以设置所需的变量


当然,您可以根据需要对多个目标和多个变量进行扩展。

您只需将变量放在make target之前:

$(PROD)/Parent: XML_BUILD_TYPE = -DPARENT
$(PROD)/Parent: \
        $(XML)/Xml.h \
        $(TOOLS_OBJS) \
        $(XML_PARENT_OBJECTS) \
        $(XML_INPUTS)
    $(CC) -o $@ $(TOOLS_OBJS) $(XML_PARENT_OBJECTS) -rdynamic $(JSON_LIB) $(CURL_LIB) $(LIBS) -lssl -lidn

$(PROD)/Child: XML_BUILD_TYPE = -DCHILD
$(PROD)/Child: \
        $(XML)/Xmlr.h \
        $(TOOLS_OBJS) \
        $(XML_CHILD_OBJECTS) \
    $(CC) $(CFLAGS) -c -o $(OBJ)/LinkDate.o  $(TOOLS)/LinkDate.c
    $(CC) -o $@ $(TOOLS_OBJS) $(XML_CHILD_OBJECTS) -rdynamic $(OBJ)/LinkDate.o $(JSON_LIB) $(CURL_LIB) $(LIBS) -lssl -lidn
您可以拥有任意数量的:

$(PROD)/Parent: XML_BUILD_TYPE = -DPARENT
$(PROD)/Parent: ANOTHERVAR = -DSOMETHING
$(PROD)/Parent: $(XML)/Xml.h $(TOOLS_OBJS) $(XML_PARENT_OBJECTS) $(XML_INPUTS)
    $(CC) -o $@ $(TOOLS_OBJS) $(XML_PARENT_OBJECTS) -rdynamic $(JSON_LIB) $(CURL_LIB) $(LIBS) -lssl -lidn

PS:
$(XML\u CHILD\u OBJECTS)
是构建所需的对象列表。有些是父级和子级的共同点,但我想将特定于子级的部分从父级构建中删除,反之亦然。递归是一种方法,是吗?谢谢你,这是一种享受!递归是一种方法。它在概念上很简单,在这样简单的情况下可能会很好地工作。有时甚至可以选择它。但是当你的make环境变得复杂时,递归也有很多缺点。我试过了,被告知“找到了多个目标,使用最后一个”。我还被告知“在设置依赖项之前,您正在运行命令”。Make在那件事上对我很刻薄!谢尔盖的回答是正确的。如果它不起作用,那么您输入的是错误的,或者您使用的是非常旧的GNU make版本。运行
make--version
;你得到了什么?另外,make不会打印这些错误(尽管它会打印类似的内容)。如果你剪切并粘贴准确的错误而不是解释错误,这会很有帮助;有时细微的差别意味着很多。如果您仍然无法让它工作,请使用您尝试过的完全相同的makefile的剪切/粘贴更新您的问题。