执行 bash 个脚本的变量中的 makefile 变量
makefile variables within variables executing bash scripts
我有一个 makefile
,我想 运行 对抗 linux (debian/Ubuntu) 和 Windows/Cygwin.
我需要根据 运行ning 环境做一些稍微不同的事情,我得出了以下代码,它应该在变量中存储一个字符串,如果是 foo
OS 是 linux,否则 foo.exe
:
EXECUTABLE_FILENAME=bash -c 'os_type=`uname`; if [ $os_type == "Linux" ]; then echo "foo"; else echo "foo.exe"; fi'
然后我想在另一个变量中使用该变量,例如:
GODEPBUILD=$(godep go build -o $(EXECUTABLE_FILENAME))
上一个 with/without 通过 $(...some stuff...)
进行的评估(请参阅下文了解我为完成这项工作所做的所有测试)
最后我想 "run" 在 makefile
的任务中的其他地方执行该命令,例如:
build-all:
@echo -e "build my project"
$(GODEPBUILD)
我试过很多不同的组合
- with/without
$(some stuff here)
,
- with/without 单引号
'
,
- with/without bash "`"
- with/without换行
bash -c '...some commands here...'
但我收到各种 bash 错误,例如:
invalid option -- 'c'
go
编译器抱怨 EXECUTABLE_FILENAME
为空,并显示此消息:flag needs an argument: -o
- 静默忽略
$(GODEPBUILD)
(我相信是因为它以某种方式评估为空命令)
我正在执行这一系列步骤,因为我需要将 go
工具链的许多命令包装到另一个名为 godep
的工具中,我还需要将其与操作的一些特定功能结合起来系统(例如我坚持使用的文件名)。我在 makefile
的开头定义了 go
工具链的许多不同 "commands",例如:
GODEP_VERSION=godep version
GODEPRESTORE=godep restore
GODEPTEST=godep go test -v
GOCLEAN=go clean
我在 makefile
任务中将这些 "commands" 称为 $(GODEP_VERSION)
(或者 -$(GODEP_VERSION)
,如果我需要忽略 stderr
),对我来说很高兴以类似的方式添加 "build command"。
make
版本是:
- 4.1 在 Ubuntu
- Cygwin 上的 4.2.1
这件事有可能吗?
我如何实现不同 "small scripts" 的这种组合来构建 make
应该 运行 在任务中的最终命令?
您当然希望 bash 命令的 output 作为文件名,对吧?您正在使用 bash 命令本身作为文件名。即 $(EXECUTABLE_FILENAME)
是由几个单词组成的字符串。当您将其传递给 godep
命令时,它会作为多个参数传递:
godep go build -o $(EXECUTABLE_FILENAME)
变为:
godep go build -o bash -c 'os_type=`uname`; if [ s_type == "Linux" ]; then echo "foo"; else echo "foo.exe"; fi'
这完全是胡说八道(请注意,$o
被扩展为 make 变量,但这是你的问题中最少的)。
您肯定要运行 bash 命令来决定文件名。您可以使用 make 的 $(shell ...)
函数 运行 一个 shell 命令:
EXECUTABLE_FILENAME = $(shell os_type=`uname` ; if [ $$os_type == Linux ]; then echo foo ; else echo foo.exe ; fi)
注意我使用 $$os_type
来引用 shell 变量,因此 make 在调用 shell.[=37= 之前不会尝试扩展 $os_type
]
但我会将其简化为:
EXECUTABLE_FILENAME = foo$(shell [ `uname` == Linux ] || echo .exe)
或者也许:
EXECUTABLE_SUFFIX = $(shell [ `uname` == Linux ] || echo .exe)
EXECUTABLE_FILENAME = foo$(EXECUTABLE_SUFFIX)
现在 make 变量 $(EXECUTABLE_FILENAME)
将扩展为文件名。
下一个问题在这里:
GODEPBUILD=$(godep go build -o $(EXECUTABLE_FILENAME))
这是什么意思?为什么将它包含在 $(...)
中?尝试 运行 一个名为 godep
的 make
函数,当然你只是想要:
GODEPBUILD = godep go build -o $(EXECUTABLE_FILENAME)
然后当您在食谱中使用它时,它会扩展为:
build-all:
@echo -e "build my project"
godep go build -o foo
或者:
build-all:
@echo -e "build my project"
godep go build -o foo.exe
N.B。作为可选(但推荐)的改进,您应该使用 :=
来设置 make 变量,否则每次使用时它们都会扩展。这意味着每次您引用使用 $(EXECUTABLE_SUFFIX)
的变量时,shell 命令又是 运行。将其更改为使用 :=
将意味着它被评估一次:
EXECUTABLE_SUFFIX := $(shell [ `uname` == Linux ] || echo .exe)
同样,您也可以对其他变量使用 :=
:
EXECUTABLE_FILENAME := foo$(EXECUTABLE_SUFFIX)
GODEPBUILD := godep go build -o $(EXECUTABLE_FILENAME)
(这些并不重要,只要 EXECUTABLE_SUFFIX
使用 :=
并且已经包含文件名即可)。
我有一个 makefile
,我想 运行 对抗 linux (debian/Ubuntu) 和 Windows/Cygwin.
我需要根据 运行ning 环境做一些稍微不同的事情,我得出了以下代码,它应该在变量中存储一个字符串,如果是 foo
OS 是 linux,否则 foo.exe
:
EXECUTABLE_FILENAME=bash -c 'os_type=`uname`; if [ $os_type == "Linux" ]; then echo "foo"; else echo "foo.exe"; fi'
然后我想在另一个变量中使用该变量,例如:
GODEPBUILD=$(godep go build -o $(EXECUTABLE_FILENAME))
上一个 with/without 通过 $(...some stuff...)
进行的评估(请参阅下文了解我为完成这项工作所做的所有测试)
最后我想 "run" 在 makefile
的任务中的其他地方执行该命令,例如:
build-all:
@echo -e "build my project"
$(GODEPBUILD)
我试过很多不同的组合
- with/without
$(some stuff here)
, - with/without 单引号
'
, - with/without bash "`"
- with/without换行
bash -c '...some commands here...'
但我收到各种 bash 错误,例如:
invalid option -- 'c'
go
编译器抱怨EXECUTABLE_FILENAME
为空,并显示此消息:flag needs an argument: -o
- 静默忽略
$(GODEPBUILD)
(我相信是因为它以某种方式评估为空命令)
我正在执行这一系列步骤,因为我需要将 go
工具链的许多命令包装到另一个名为 godep
的工具中,我还需要将其与操作的一些特定功能结合起来系统(例如我坚持使用的文件名)。我在 makefile
的开头定义了 go
工具链的许多不同 "commands",例如:
GODEP_VERSION=godep version
GODEPRESTORE=godep restore
GODEPTEST=godep go test -v
GOCLEAN=go clean
我在 makefile
任务中将这些 "commands" 称为 $(GODEP_VERSION)
(或者 -$(GODEP_VERSION)
,如果我需要忽略 stderr
),对我来说很高兴以类似的方式添加 "build command"。
make
版本是:
- 4.1 在 Ubuntu
- Cygwin 上的 4.2.1
这件事有可能吗?
我如何实现不同 "small scripts" 的这种组合来构建 make
应该 运行 在任务中的最终命令?
您当然希望 bash 命令的 output 作为文件名,对吧?您正在使用 bash 命令本身作为文件名。即 $(EXECUTABLE_FILENAME)
是由几个单词组成的字符串。当您将其传递给 godep
命令时,它会作为多个参数传递:
godep go build -o $(EXECUTABLE_FILENAME)
变为:
godep go build -o bash -c 'os_type=`uname`; if [ s_type == "Linux" ]; then echo "foo"; else echo "foo.exe"; fi'
这完全是胡说八道(请注意,$o
被扩展为 make 变量,但这是你的问题中最少的)。
您肯定要运行 bash 命令来决定文件名。您可以使用 make 的 $(shell ...)
函数 运行 一个 shell 命令:
EXECUTABLE_FILENAME = $(shell os_type=`uname` ; if [ $$os_type == Linux ]; then echo foo ; else echo foo.exe ; fi)
注意我使用 $$os_type
来引用 shell 变量,因此 make 在调用 shell.[=37= 之前不会尝试扩展 $os_type
]
但我会将其简化为:
EXECUTABLE_FILENAME = foo$(shell [ `uname` == Linux ] || echo .exe)
或者也许:
EXECUTABLE_SUFFIX = $(shell [ `uname` == Linux ] || echo .exe)
EXECUTABLE_FILENAME = foo$(EXECUTABLE_SUFFIX)
现在 make 变量 $(EXECUTABLE_FILENAME)
将扩展为文件名。
下一个问题在这里:
GODEPBUILD=$(godep go build -o $(EXECUTABLE_FILENAME))
这是什么意思?为什么将它包含在 $(...)
中?尝试 运行 一个名为 godep
的 make
函数,当然你只是想要:
GODEPBUILD = godep go build -o $(EXECUTABLE_FILENAME)
然后当您在食谱中使用它时,它会扩展为:
build-all:
@echo -e "build my project"
godep go build -o foo
或者:
build-all:
@echo -e "build my project"
godep go build -o foo.exe
N.B。作为可选(但推荐)的改进,您应该使用 :=
来设置 make 变量,否则每次使用时它们都会扩展。这意味着每次您引用使用 $(EXECUTABLE_SUFFIX)
的变量时,shell 命令又是 运行。将其更改为使用 :=
将意味着它被评估一次:
EXECUTABLE_SUFFIX := $(shell [ `uname` == Linux ] || echo .exe)
同样,您也可以对其他变量使用 :=
:
EXECUTABLE_FILENAME := foo$(EXECUTABLE_SUFFIX)
GODEPBUILD := godep go build -o $(EXECUTABLE_FILENAME)
(这些并不重要,只要 EXECUTABLE_SUFFIX
使用 :=
并且已经包含文件名即可)。