【发布时间】:2020-12-05 16:25:21
【问题描述】:
我正在尝试将 GNU make 官方文档中的示例改编为我的用例: GNU make - Example of a Conditional
libs_for_gcc = -lgnu
normal_libs =
ifeq ($(CC),gcc)
libs=$(libs_for_gcc)
else
libs=$(normal_libs)
endif
foo: $(objects)
$(CC) -o foo $(objects) $(libs)
所以,我创建了这个原型:
libs_for_gcc="gcc libs"
normal_libs="normal libs"
libs=
all: do_nothing
@echo "all: done."
do_nothing:
@echo "do_nothing: done."
example:
@echo "example: go ..."
@echo "example - cc: '$(CC)'"
@echo "libs_for_gcc: $(libs_for_gcc)"
@echo "normal_libs: $(normal_libs)"
@echo "libs: $(libs)"
ifeq ($(CC),gcc)
libs=$(libs_for_gcc) && echo "libs: '$$libs'"
@echo "example - libs: '$(libs)'"
else
libs=$(normal_libs) && echo "libs: '$$libs'"
@echo example - libs: $(libs)
endif
@echo "example - libs: '$(libs)'"
@echo "example: done."
test: libs += " -Ddebug"
test: example foo
bar:
@echo "bar: go ..."
ifeq (${libs}, "")
@echo "bar - libs: empty"
@echo "assigning libs"
libs=$(libs_for_gcc)
else
@echo "bar - libs: not empty"
@echo "bar - libs: '${libs}'"
endif
@echo "bar - libs: '${libs}'"
@echo "bar: done."
foo:
@echo "foo: go ..."
ifneq ("$(libs)", "")
@echo "foo - libs: not empty"
@echo "foo - libs: '$(libs)'"
else
@echo "foo - libs: empty"
endif
@echo "foo: done."
现在当我使用$ make 运行默认目标时
它只是产生:
$ make
example: go ...
example - cc: 'cc'
libs_for_gcc: gcc libs
normal_libs: normal libs
libs:
libs="normal libs"
example - libs:
example - libs: ''
example: done.
我看到libs 的值没有按预期更改。
当我运行 make bar 目标时,它会产生:
$ make bar
bar: go ...
bar - libs: not empty
bar - libs: ''
bar - libs: ''
bar: done.
这里libs不是空的,但里面什么都没有。
当我运行 make foo 目标时,它会产生:
$ make foo
foo: go ...
foo - libs: empty
foo: done.
这里libs理解为空
当我看到libs 没有正确更改时,我尝试将语法更改为:
example:
# [...]
ifeq ($(CC),gcc)
libs := $(libs_for_gcc)
@echo "example - libs: '$(libs)'"
else
libs := $(normal_libs)
@echo example - libs: $(libs)
endif
然后我得到 GNU make 错误:
$ make
example: go ...
example - cc: 'cc'
libs_for_gcc: gcc libs
normal_libs: normal libs
libs:
libs := "normal libs"
/bin/sh: 1: libs: not found
Makefile:7: recipe for target 'example' failed
make: *** [example] Error 127
我找不到有关此行为的任何文档,因此我很感激任何建议。
编辑:
- 添加了
all和test目标。
背景:
GNU make 命令是用于打包和部署软件的工具链的重要组成部分,因此在系统管理员和 DevOps 工程师的日常工作中非常重要。
-
Debian 和 RPM 打包使用 GNU make 来打包软件。
Makefile Driven Packaging
它运行
./configure && make && make install命令序列。 -
Travis CI 工作流程使用 GNU make 来运行测试套件。
C Language Automated Testing
它运行
./configure && make && make test序列。
所有完全不同的用例都由相同的 Makefile 管理。 现在,对于我的具体用例,我正在设置 Travis CI 工作流程序列,以便为我的静态链接源代码库启用 自动化测试。 因此,与打包序列相反,自动化测试序列需要调试功能和高级输出评估来生成有意义的测试。 我希望测试检查错误报告和内存使用报告,以提醒我任何隐藏的错误。
使用关于在目标声明行设置变量的建议,我能够将libs 更改为test、example 和foo 目标。
我还看到了关于 Bash 变量 libs 的重要提示,它只在同一行有效:
$ make
do_nothing: done.
all: done.
$ make test
example: go ...
example - cc: 'cc'
libs_for_gcc: gcc libs
normal_libs: normal libs
libs: -Ddebug
libs="normal libs" && echo "libs: '$libs'" ;
libs: 'normal libs'
example - libs: -Ddebug
example - libs: ' -Ddebug'
example: done.
foo: go ...
foo - libs: empty
foo - libs: ' -Ddebug'
foo: done.
配方libs=$(libs_for_gcc) && echo "libs: '$$libs'" 表明创建了一个新的Bash 变量libs,它不会影响GNU make 变量。
条件 ifneq ($(libs),) 仍然无法检测到 libs 已为 test 目标设置。
【问题讨论】: