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: Siyuan Chen <chansey97 <at> gmail.com>
Subject: bug#77430: closed (Re: bug#77430: compilation-start should
 remember shell-file-name)
Date: Sat, 19 Apr 2025 13:50:04 +0000
[Message part 1 (text/plain, inline)]
Your bug report

#77430: compilation-start should remember shell-file-name

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to 77430 <at> debbugs.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: 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.

[Message part 3 (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 4 (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 5 (text/html, inline)]
[0001-Remember-the-original-shell-file-name-so-we-can-use-.patch (text/plain, attachment)]

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.