5

I use Emacs 25.1 on my Windows XP laptop both as a command-line app (on ConEmu terminal emulator with MSYS bash as the shell) and as the GUI Emacs. I mainly use Emacs to test and compile programs, so I frequently use Mono C# compiler (gmcs) and GCC. The path of gmcs is defined inside the Windows environment variable Path, so when I use gmcs in GUI Emacs, it works.

But the path of GCC (/c/MinGW/bin) is defined inside ~/.bashrc and if I try to use GCC in GUI Emacs, it doesn't work.

If I start emacs -nw from within ConEmu terminal and try to compile a C code using M-x compile & gcc my-c-code.c -o my-c-code.exe there's no problem: Emacs recognizes the gcc command and does the compilation.

When I try to do the same thing in GUI Emacs it says:

gcc my-c-code.c -o my-c-code.exe
/usr/bin/bash: gcc: command not found

To introduce the GCC's path into Emacs's exec-path I've added these into .emacs file:

(setq exec-path (append exec-path '("C:/MinGW/bin")))
(setenv "PATH" (concat "C:/MinGW/bin"  (getenv "PATH")))
(setq shell-file-name "C:/msys32/usr/bin/bash.exe")

but none of them helped. The last line helped only if I open a shell within GUI Emacs, but not at the M-x compile stage.

How can I define the path of GCC inside the .emacs file? Note that I might add the path of GCC in the Windows env variable Path, but I don't want to solve it that way, I'd like to solve it the Emacs way. Thank you!

2
  • 1
    I think missed a semicolon in your setenv, it should be (setenv "PATH" (concat "C:/MinGW/bin;" (getenv "PATH")))
    – npostavs
    Commented Sep 25, 2016 at 16:26
  • Hey that worked! Can't figure out why those semicolons are strictly necessary to make it work, though. More importantly, on this SO page, on the selected answer there are no semicolons.On this page semicolons were used but I haven't noticed them. Could you please post an answer along with a note stating why semicolons are necessary in this case? Thanks.
    – Terry
    Commented Sep 25, 2016 at 17:01

1 Answer 1

10

PATH vs exec-path

The PATH environment variable lists directories for programs to find executable files (when executing a non-absolute filename). The exec-path Emacs variable lists directories for Emacs to find executable files (again, when executing a non-absolute filename). The value of exec-path takes its value from the environment variable PATH when starting up (hence, PATH does effectively tell Emacs where to find executables, just like all other programs).

exec-path is for things run directly by Emacs

on this SO page, on the selected answer there are no semicolons.

That answer deals with modifying shell-file-name, i.e., the shell that Emacs runs. If you use a relative file-name for shell-file-name, exec-path will be consulted, hence there is no reason to worry about path separators.

PATH is for everything else

The compile-command is a shell command, i.e., Emacs runs a shell and then tells that shell to run compile-command. This shell inherits the PATH environment variable from Emacs, but of course it doesn't see exec-path. Therefore, if you use a relative file-name in compile-command, the PATH environment variable will be consulted.

Filenames in PATH must be (semi)colon separated

On most operating systems (i.e., all the ones that Emacs runs on), environment variables can only hold strings, so the list has to be encoded by separating the directory names with a special character. On Windows this character is the semi-colon, on Unix-like systems it's a colon. To write portable elisp, use the variable path-separator which has the right character for the current system.


Hence the correct answer for this question is:

(setenv "PATH" (concat "C:/MinGW/bin;" (getenv "PATH")))

Or to make things bit neater, and keep exec-path and PATH synchronized:

(add-to-list 'exec-path "C:/MinGW/bin")
(setenv "PATH" (mapconcat #'identity exec-path path-separator))
1
  • 1
    The neater version looks very practical and I've put it in my .emacs file. The distinction between the exec-path and the Path of Emacs is quite clear now. Thank you.
    – Terry
    Commented Sep 25, 2016 at 22:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.