如何让Emacs识别bash环境变量进行编译?

20
我正在尝试通过Emacs编译模式编译u-boot,看起来Emacs不知道如何查找bash环境变量。即使我设置了它们,并且可以通过Emacs shell仿真进行编译,编译模式仍然尝试编译,就好像它们不存在一样。
我需要做什么才能使其更加环境意识到位?
3个回答

33

你可以尝试在你的.emacs文件中添加类似以下的内容:

(let ((path (shell-command-to-string ". ~/.bashrc; echo -n $PATH")))
  (setenv "PATH" path)
  (setq exec-path 
        (append
         (split-string-and-unquote path ":")
         exec-path)))
根据你是否在.bash_profile.bashrc中设置了环境变量,你可能需要稍微调整这段代码。这个例子是针对PATH变量的,它有点特别(因为你还必须在Emacs中设置exec-path),但可以扩展到适用于任意变量 - 你可以有一个变量列表,必须从.bashrc读取并设置到Emacs中。
我不确定你是否在使用OS X或GNU/Linux。在Linux中从GUI菜单栏启动Emacs通常会导致与从命令行启动的Emacs不具有相同的PATH。这个问题可以追溯到第一个xdm Xsession脚本,虽然它们很容易修复(基本上使用一个Xsessionwrapper脚本,执行exec $SHELL -c Xsession ,以便在运行用户的Xsession之前运行shell),但很长一段时间以来没有人费心去解决它(我怀疑也不会有人)。据我所知,这个问题甚至存在于现代的xdm后代(如kdmgdm)中。
在OS X上,处理环境变量是另一个完全不同的问题,要获取您的ENV变量,通常必须像这样从命令行运行Emacs:/Applications/Emacs.app/Contents/MacOS/Emacs,或者尝试一下~/.MacOSX/environment.plist。不过,我提供的代码段应该适用于这两种情况。
更新:
最近,通过exec-path-from-shell扩展,这个过程变得更容易了。它以更或多或少相同的方式设置emacs $PATH,但使用扩展通常比自己进行修改更可取。

这解决了我在 Flymake 中使用 perlbrew 的正确 Perl 版本的问题。与 perlbrew-mini.el 不同。 - titanofold
1
exec-path-from-shell 很棒,解决了我的问题,使得 ensime 可以启动并避免了 wrong type argument stringp nil 错误。 - kikulikov
你为什么使用split-string-and-unquote而不是split-string? - Clément
尽管这个答案已经很明确了,但对于那些匆忙浏览的人来说,这个答案的前两行正是我所搜寻的:(let ((MYVAR (shell-command-to-string ". ~/.bashrc; echo -n $MYVAR"))) (setenv "MYVAR" MYVAR)) - Jesse W. Collins
这解决了我的问题。谢谢。 - Because i hate myself

7

这里是启动emacs进程的环境变量:

— Command: getenv var

This function returns the value of the environment variable var, as a string. var should be a string. If var is undefined in the environment, getenv returns nil. It returns ‘""’ if var is set but null. Within Emacs, a list of environment variables and their values is kept in the variable process-environment.

      (getenv "USER")
           ⇒ "lewis"

— Variable: process-environment

This variable is a list of strings, each describing one environment variable. The functions getenv and setenv work by means of this variable.

      process-environment
      ⇒ ("PATH=/usr/local/bin:/usr/bin:/bin"
          "USER=lewis"
          "TERM=xterm"
          "SHELL=/bin/bash"
          "HOME=/home/lewis"
          ...)
您似乎假设emacs是从bash会话启动的。然而,通常在X下启动的进程是从sh会话启动的,这将不会读取您在~/.bashrc脚本中设置的环境变量。一个简单的方法是更改您的~/.xinitrc文件以使用bash而不是sh(可以在文件顶部添加#!/bin/bash)。
来源:gnu.org

1
你是不是想说 #!/bin/bash - Eleno
谢谢,@Elena。已修复。 :) - dmvianna

3

这并不是严格回答你的问题,但你总可以在make命令行中传递环境变量。例如:M-xcompileRETmake -k CXXFLAGS='-Wall'RET


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接