GNU bug report logs - #77430
compilation-start should remember shell-file-name

Previous Next

Package: emacs;

Reported by: Siyuan Chen <chansey97 <at> gmail.com>

Date: Tue, 1 Apr 2025 13:43:06 UTC

Severity: normal

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: tracker <at> debbugs.gnu.org
Subject: bug#77430: closed (compilation-start should remember shell-file-name)
Date: Sat, 19 Apr 2025 13:50:03 +0000
[Message part 1 (text/plain, inline)]
Your message dated Sat, 19 Apr 2025 16:48:57 +0300
with message-id <86ecxo8do6.fsf <at> gnu.org>
and subject line Re: bug#77430: compilation-start should remember shell-file-name
has caused the debbugs.gnu.org bug report #77430,
regarding compilation-start should remember shell-file-name
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs <at> gnu.org.)


-- 
77430: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=77430
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: Siyuan Chen <chansey97 <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: compilation-start should remember shell-file-name
Date: Tue, 1 Apr 2025 21:42:21 +0800
[Message part 3 (text/plain, inline)]
Background:

Recently, I've been setting up a Haskell compilation environment with Emacs
on Windows. The project depends on diagrams-cairo, which depends on GTK+,
so I have to build it via msys64 with MINGW. It works well in a non Emacs
environment, so I'd like to adapt it to the Emacs environment.

Everything is OK, except when I press 'g' in the *compilation* buffer.

To simplify the problem, below only the minimal test is provided.

Reproduce steps:

1. Create a file test.el in E:/tmp

2. Open that file and paste the following code
```
(defun my/compile ()
  (interactive)
  (let ((shell-file-name "C:/msys64/usr/bin/bash")
        (compilation-environment
"PATH=/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl")
        )
    (compile "ls")
    ))
```
NOTE: You can think of "ls" as a compilation command such as "stack build"
in Haskell.

3. Evaluate Last S-expression.

4. M-x my/compile

The *compilation* buffer lists the files normally.

5. Press 'g' in the *compilation* buffer, i.e. `recompile'.

The expected behavior: List the files again.

The actual behavior: Compilation exited abnormally.

The problem is that `recompile' does not realize that `shell-file-name' has
been updated to bash. It still uses the default cmdproxy.

I have created a patch to workaround the issue. It remembers the original
`shell-file-name' in `compilation-start', so we can use it when we
`recompile'.

Thanks.

Best regards,
Siyuan Chen
[Message part 4 (text/html, inline)]
[0001-Remember-the-original-shell-file-name-so-we-can-use-.patch (text/plain, attachment)]
[Message part 6 (message/rfc822, inline)]
From: Eli Zaretskii <eliz <at> gnu.org>
To: Siyuan Chen <chansey97 <at> gmail.com>
Cc: 77430-done <at> debbugs.gnu.org
Subject: Re: bug#77430: compilation-start should remember shell-file-name
Date: Sat, 19 Apr 2025 16:48:57 +0300
> From: Siyuan Chen <chansey97 <at> gmail.com>
> Date: Fri, 4 Apr 2025 16:15:06 +0800
> Cc: 77430 <at> debbugs.gnu.org
> 
> > Sorry, I don't understand: are you saying that you cannot arrange for
> the buffer-local value of shell-file-name to point to Bash and stay
> that way for the subsequent commands?  If you need to use
> with-current-buffer or something similar, it should be easy no?
> 
> The original problem is not about `compile' but `recompile', i.e. press 'g' in the *compilation* buffer. The
> *compilation* buffer doesn't know anything about the last shell-file-name, so it uses cmdproxy by default. 
> 
> Anyway, this is no longer a problem now, see below.
> 
> > I think this is the cleanest solution for problems like this on
> Windows, since you don't really want to override shell-file-name, you
> just want to invoke the commands via Bash.
> 
> Your method really inspired me. Thank you so much! 
> 
> Based on it, I've redesigned my compilation workflow. Basically, whenever users invoke
> `sc-haskell-projectile-stack-compile' (a tailored compile command integrated with projectile), it firstly
> generates two files in the Haskell project folder: 
> 
> .emacs_stack_launch.bat
> ```
> set MSYSTEM=MINGW32
> "c:/Users/Chansey/AppData/Local/Programs/stack/x86_64-windows/msys2-20230526/usr/bin/bash" --login
> "e:/my-haskell-project/.emacs_stack_launch_script.sh" %*
> ```
> 
> .emacs_stack_launch_script.sh
> ```
> export STACK_ROOT=/c/sr
> export
> PATH=/c/env/haskell/stack/v2.15.1:/c/Users/Chansey/AppData/Roaming/local/bin:/c/PROGRA~1/Git/cmd:$PATH
> 
> $*
> ```
> 
> then it calls (compile ".emacs_stack_launch.bat stack build").
> 
> This method is working great so far. Plus, the file generation brings several benefits:
> 
> 1. We can set local variables in .dir-locals (e.g. msys2-path, environment-variables) per project for
> fine-grained control over compilation.
> 
> 2. No need to tailored `recompile'. It just uses the last generated files. So it works pretty well when users
> press 'g' in the *compilation* buffer.
> 
> 3. Support all the compile commands and opts, like stack build, stack run, stack build --test, etc.
> 
> 4. Easy debugging with .emacs_stack_launch.bat and .emacs_stack_launch_script.sh. 
> 
> The code is something like this:
> 
> ```
> (defun sc-haskell-projectile-stack--run-project-cmd (command)
>   (let* ((default-directory (projectile-compilation-dir))
>          (command (projectile-read-command
>                    "Compile command: "
>                    (or projectile-project-compilation-cmd
>                        command))))
>     (sc-haskell-projectile-stack--gen-launch-file)
>     (sc-haskell-projectile-stack--gen-launch-script-file)
>     (compile (format "%s %s"
>                      ".emacs_stack_launch.bat"
>                      command)
>              projectile-compile-use-comint-mode)))
> 
> (defun sc-haskell-projectile-stack-compile ()
>   (sc-haskell-projectile-stack--run-project-cmd "stack build"))
> 
> (defun sc-haskell-projectile-stack-test ()
>   (sc-haskell-projectile-stack--run-project-cmd "stack build --test"))
> 
> (defun sc-haskell-projectile-stack-run ()
>   (sc-haskell-projectile-stack--run-project-cmd "stack run"))
> ```
> 
> Additionally, I also created a projectile-based shell command, which has to be different from projectile-based
> compile command.
> 
> ```
> (defun sc-haskell-projectile-stack-shell ()
>   (interactive)
>   (let ((current-prefix-arg 4)
>         (explicit-shell-file-name
>          (expand-file-name "usr/bin/bash" sc-haskell-projectile-stack-msys2-path))
>         (explicit-bash-args
>          '("--login" "--noediting" "-i")))
>     (sc-haskell-projectile-stack--gen-msys2-bashrc-init-file)
>     (with-environment-variables (("MSYSTEM" "MINGW32"))
>       (call-interactively 'projectile-run-shell))))
> ```
> 
> Unlike the previous method, this one still rebinds explicit-shell-file-name, otherwise we have to call "bash -
> -login --noediting -i" in the .emacs_stack_launch_script.sh, which would invoke bash twice — something I'd
> rather avoid (it still can work though).
> 
> My solution is to add a hook in .bashrc
> 
> ```
> if [ -f $HOME/.bashrc_init.sh ]; then
>     . $HOME/.bashrc_init.sh
>     rm $HOME/.bashrc_init.sh
> fi
> ```
> 
> Basically, whenever users invoke `sc-haskell-projectile-stack-shell, it generates .bashrc_init.sh in the msys2
> home USER folder. The commands in .bashrc_init.sh are similar to those in emacs_stack_launch_script and
> can, of course, be configured via .dir-locals.el. It might seem a bit unusual, but it works well so far. 
> 
> Just like to share my current design here — any suggestions would be greatly appreciated.

Thanks.

I guess we can close this bug now.


This bug report was last modified 34 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.