我有一个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 -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
版本是:
这件事有可能吗?
我怎样才能实现不同"小脚本的组合"构建make
应在任务中运行的最终命令?
答案 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
,因此已经包含文件名。)