我在这里和其他地方找到了很多答案,但没有一个有效。请帮帮我。
我需要设置一些环境变量,部分是在一些脚本中完成的,从主脚本调用,部分直接调用。这是一个显示不需要的行为的最小Makefile:
FC := ifort
SHELL := /bin/bash
some_target: load_ifort
$(FC) file.f
load_ifort:
source /usr/local2/bin/ifort-compilervars.sh ia32
export LM_LICENSE_FILE=/usr/local2/misc/intel2013/flexlm/server.lic
如果我调用make,我会收到“ifort:command not found”错误。如果我在调用make之前在命令行上手动执行两个comamnds,那么找到ifort并且一切都很好。
我缺少什么?
答案 0 :(得分:2)
配方中的每一行都在一个单独的子shell中执行。所以你创建一个shell来源.sh
文件,然后退出并忘记所有内容,然后另一个shell以一个干净的平板开始。
在您的情况下,直接的解决方案是在单个变量中收集所有这些命令。我已将LM_LICENSE_FILE
分配考虑在内,因为可以直接在Make中完成,但您也可以将其包含在FC
变量中。
LM_LICENSE_FILE := /usr/local2/misc/intel2013/flexlm/server.lic
export LM_LICENSE_FILE
FC := source /usr/local2/bin/ifort-compilervars.sh ia32; \
ifort
some_target:
$(FC) file.f
如果make命令可以直接运行shell命令,你可以include
,或者可以通过一个简单的脚本将sh
文件翻译成Make命令。
另一种选择是在PATH
中创建一个简单的包装器;可以称之为fc
:
#!/bin/sh
. /usr/local2/bin/ifort-compilervars.sh ia32
ifort "$@"
然后只使用当前fc
的{{1}}。 (如果$(FC)
文件包含Bash结构,则无论名称如何,都应将shebang更改为ifort-compilervars.sh
。)
答案 1 :(得分:1)
通常,只有单线程shell命令“工作”。从关于“bash”的评论来看,你似乎可能正在使用GNU make。在您的示例中,GNU make手册index中找不到“source”一词。 (如果你在一个有效的例子中找到了这个,那么从那开始会很有帮助)。有两种类型的感兴趣的变量:
后者将包括$ PATH,用于查找程序。要更新它,您需要shell命令。但是(在make程序中缺少一些特殊规定),shell脚本中的导出变量不会 up 传递给make程序,并且可用于makefile的下一行。
您可以重新组织makefile以提供一个规则,该规则将源命令和其他初始化组合到一个shell命令中,然后将该命令重复(将这些变量携带)到子进程中,然后进行编译。像
这样的东西build:
sh -c "source /usr/local2/bin/ifort-compilervars.sh ia32; \
export LM_LICENSE_FILE=/usr/local2/misc/intel2013/flexlm/server.lic; \
$(MAKE) some_target"
some_target: load_ifort
$(FC) file.f