执行bash脚本的变量中的makefile变量

时间:2017-10-10 16:39:31

标签: bash makefile toolchain go-toolchain

我有一个makefile我想对linux(debian / Ubuntu)和Windows / Cygwin运行。

我需要根据运行环境做一些稍微不同的事情,我发布了以下代码片段,如果操作系统是linux,则应该在变量中存储一个字符串foo,否则{ {1}}:

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)) (见下面我为使这项工作所做的所有测试)

最后我想"跑"该命令位于$(...some stuff...)内任务中的其他位置,如:

makefile

我尝试了很多不同的组合

  • 有/无build-all: @echo -e "build my project" $(GODEPBUILD)
  • 有/无单引号$(some stuff here)
  • 有/没有bash"`"
  • 有/无包裹'

但是我得到了各种各样的bash错误,例如:

  • bash -c '...some commands here...'
  • invalid option -- 'c'编译器抱怨go为空,并显示以下消息:EXECUTABLE_FILENAME
  • 默认忽略flag needs an argument: -o(我相信因为它以某种方式评估为空命令)

我正在执行这一系列步骤,因为我需要将$(GODEPBUILD)工具链的许多命令包装到另一个名为go的工具中,我还需要将其与操作系统的某些特定功能相结合(例如我坚持使用的文件名。)我已经定义了许多不同的"命令" godep开头的go工具链,例如:

makefile

我称之为"命令" GODEP_VERSION=godep version GODEPRESTORE=godep restore GODEPTEST=godep go test -v GOCLEAN=go clean 之内的makefile任务内部(或$(GODEP_VERSION),如果我需要忽略-$(GODEP_VERSION)),对我而言,添加"构建命令&#34很不错;以类似的方式。

stderr版本是:

  • 4.1 on Ubuntu
  • 4.2.1 on Cygwin

这件事有可能吗?

我怎样才能实现不同"小脚本的组合"构建make应在任务中运行的最终命令?

1 个答案:

答案 0 :(得分:1)

当然你想要bash命令的输出作为文件名,对吧?您正在使用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变量,因此在调用shell之前,请不要尝试展开$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))

这是什么意思?为什么要将其括在$(...)中?这会尝试运行名为make的{​​{1}}函数,当然您只需要:

godep

然后当您在配方中使用它时,它将扩展为:

GODEPBUILD = godep go build -o $(EXECUTABLE_FILENAME)

或者:

build-all:
   @echo -e "build my project"
   godep go build -o foo

N.B。作为可选(但建议)的改进,您应该使用build-all: @echo -e "build my project" godep go build -o foo.exe 来设置make变量,否则它们会在每次使用时得到扩展。这意味着每次引用使用:=的变量时,都会再次运行shell命令。将其更改为使用$(EXECUTABLE_SUFFIX)将意味着它会被评估一次:

:=

同样,您也可以将EXECUTABLE_SUFFIX := $(shell [ `uname` == Linux ] || echo .exe) 用于其他变量:

:=

(这些不重要,只要EXECUTABLE_FILENAME := foo$(EXECUTABLE_SUFFIX) GODEPBUILD := godep go build -o $(EXECUTABLE_FILENAME) 使用EXECUTABLE_SUFFIX,因此已经包含文件名。)