在Lua-i18n上工作时,我试图更改Makefile,以便用户可以使用他们感兴趣的功能来编译项目,即Makefile定义了一些C宏,它将禁用相应的代码。在Makefile中对此进行定义很简单,但是在以可移植性为目标时,摆脱链接到如此定义的功能的不必要的编译依赖项并不是那么简单。实际上,该项目旨在尽可能少地修改原始代码,并添加尽可能少的依赖项(可能没有)。因此,这里有一些相关的链接http://pubs.opengroup.org/onlinepubs/009695399/utilities/make.htmlhttp://www.netbsd.org/docs/pkgsrc/makefile.htmlhttp://netbsd.gw.com/cgi-bin/man-cgi?make+1+NetBSD-5.0.1+i386http://gallium.inria.fr/blog/portable-conditionals-in-makefiles/https://docs.google.com/document/d/1oUR7iMnaNzkeT3TTOS-Gwul6_V3TE8caIDAd1FwPyNc/edit#https://www.gnu.org/software/make/manual/html_node/Conditional-Syntax.htmlhttps://www.mkssoftware.com/docs/man5/makefile.5.asp这是一个似乎可以在带有GNU Make的Fedora 24桌面上运行的解决方案。但是,我想知道这样的解决方案是否可以与任何(合理的)现代实施一起使用。cflag= -D CODE_SWITCHresolved_conditional_cflag!= test -n "$(cflag)" && echo "$(cflag)"conditional_dep= additional_dep.cmandatory_dep= dep0.c dep1.cresolved_conditional_dep!= test -n "$(cflag)" && echo "$(conditional_dep)"all_dep= $(mandatory_dep) $(resolved_conditional_dep)all: target @echo building code with flag $(resolved_conditional_cflag) @echo ${SHELL}target: $(all_dep) @echo building $@ which depends on $(all_dep)dep0.c: @echo building dep0.cdep1.c: @echo building dep1.cadditional_dep.c: @echo building $@想法是用户注释行cflag= -D CODE_SWITCH,仅此,编译器将不会处理相关的依赖项。那么,这样的解决方案是否可以移植?它依赖于Shell扩展!=和test命令。我认为最后一个可能是POSIX,但我可能错了。更一般而言,它们可能是我在这里不知道的可移植性问题。请注意,对于此特定需求,“使用CMake,自动工具或其他工具”不是理想的答案。 最佳答案 !=仅在GNU make 4.0及更高版本中可用。也不是POSIX;它被添加到GNU make中以实现与BSD make的可移植性,并被提议包含在POSIX规范中,但目前尚未被接受。我不知道仅使用纯可移植的make(POSIX)来基于make宏的内容来更改目标的先决条件的任何方法。如果您愿意使用GNU make,那么(至少现在),使用$(shell ...)比!=更可移植。虽然如果您假设使用GNU make,则有更好的方法来处理此问题,而根本不需要外壳。如果要使用!=来获得BSD make的可移植性,请确保在文档中添加注释,说明您需要GNU make 4.0或更高版本。注意,通常不要在makefile文件中的变量名和赋值运算符之间放置空格。例如最好写FOO != bar,而不是FOO!=bar或FOO!= bar。编辑Chrono Kitsune讨论的一种选择是使用一点递归。它看起来像这样:cflag= -D CODE_SWITCHconditional_dep= additional_dep.cmandatory_dep= dep0.c dep1.call_dep= $(mandatory_dep)all: target @echo building code with flag $(cflag) @echo ${SHELL}target: $(mandatory_dep) @all_dep='$^'; if test -n "$(cflag)"; then \ all_dep='$^ $(conditional_dep)'; \ $(MAKE) $(conditional_dep); \ fi; \ echo building $@ which depends on $$all_depdep0.c: @echo building dep0.cdep1.c: @echo building dep1.cadditional_dep.c: @echo building $@如果不必一定要依赖注释cflag本身,另一种替代方法是使用递归变量命名。看起来像这样:SWITCH = enabledenabled_cflag = -D CODE_SWITCHenabled_dep = additional_dep.cmandatory_dep = dep0.c dep1.ccflag = $($(SWITCH)_cflag)all_dep = $(mandatory_dep) $($(SWITCH)_dep)all: target @echo building code with flag $(cflag) @echo ${SHELL}target: $(all_dep) echo building $@ which depends on $(all_dep)dep0.c: @echo building dep0.cdep1.c: @echo building dep1.cadditional_dep.c: @echo building $@现在,如果您注释掉SWITCH设置,或者在make命令行上将其设置为空,那么这些元素将被关闭(因为$($(SWITCH)_cflag)会扩展不存在/空变量_cflag而不是)。大多数版本的make(但不是全部)都支持递归变量命名。关于c - 有一种可移植的方法来使Makefile中的可移植可选依赖项吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40772835/