homebrew-emacs-plus
homebrew-emacs-plus copied to clipboard
[General]: libgccjit.so error invoking gcc driver
Issue description
After updating to Sequoia I get the titular error every time I launch Emacs Plus from the applications folder or a saved-to-dock Emacs Plus and then run M-x.
I do not get the error in question when launching Emacs Plus from the command line, interestingly enough.
Pretty sure it's related to https://github.com/d12frosted/homebrew-emacs-plus/issues/720
Env injection is broken for whatever reason. Frankly, I will not have any time soon to investigate, so hopefuly as more people upgrade, someone will be able to spend some time investigating.
I wonder if using exce-path-from-shell solves the issue.
Pretty sure it's related to #720
This is the exact problem I ran into which led me to looking into the paths thing, so I'd assume the same.
Prior to relying on emacs-plus' automatic path stuff I was using exec-path-from-shell so I'd imagine that could be a good fallback here too.
Though in my case I'm just explicitly setting the value from the Info.plist via a few lines at the top of my .emacs so that I theoretically get exactly what emacs-plus would be giving me:
;; Temp: Explicitly set PATH environment variable and update exec-path to match it.
;; (the string here should be copied from the PATH in Emacs.app/Contents/Info.plist)
(setenv "PATH" "/opt/homebrew/bin:/opt/homebrew/sbin:...etc etc...")
(setq exec-path (split-string (getenv "PATH") path-separator))
;; Temp: Explicitly set PATH environment variable and update exec-path to match it. ;; (the string here should be copied from the PATH in Emacs.app/Contents/Info.plist) (setenv "PATH" "/opt/homebrew/bin:/opt/homebrew/sbin:...etc etc...") (setq exec-path (split-string (getenv "PATH") path-separator))
@efroemling Thanks, this solution worked for me as well. Which kinda surprised me because the native compilation log was saying the libgccjit library emutls_w wasn't found. And only when compiling a handful of my packages. Sent me into the depths of the gcc directory...this solution is...much simpler 😅
Pretty sure it's related to #720
This is the exact problem I ran into which led me to looking into the paths thing, so I'd assume the same.
Prior to relying on emacs-plus' automatic path stuff I was using exec-path-from-shell so I'd imagine that could be a good fallback here too.
Though in my case I'm just explicitly setting the value from the Info.plist via a few lines at the top of my .emacs so that I theoretically get exactly what emacs-plus would be giving me:
;; Temp: Explicitly set PATH environment variable and update exec-path to match it. ;; (the string here should be copied from the PATH in Emacs.app/Contents/Info.plist) (setenv "PATH" "/opt/homebrew/bin:/opt/homebrew/sbin:...etc etc...") (setq exec-path (split-string (getenv "PATH") path-separator))
Can confirm this works for me as well. Thank you, kind internet stranger!
In my environment, setting the PATH as per efroemling's instructions did not work. I got the impression that it worked, but then noticed again the exact same error.
M-x getenv PATH: ~/bin:~/go/bin:~/.pyenv/plugins/pyenv-virtualenv/shims/:~/.pyenv/syms/:~/.sdkman/candidates/java/current/bin:opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
On the other hand, now looking for libgccjit.so I don't seem to find it anywhere.
What package is it coming with and where is it supposed to be?
Update: I see libgccjit being installed, but there's no .so (only .dylibs)
Decided to try enabling native compilation and got the libgccjit library emutls_w error other folk have encountered. It sent me down a right rabbit hole but setting the path like @efroemling said worked a treat.
One quick extra bit info, @EXT-OWL mentioned exec-path-from-shell, I am using that still but was still encountering the issue. I set the path manually within my early-init.el, that's what fixed this. Perhaps shifting exec-path-from-shell to earlier in the process would've worked, I may try that, but it would've meant extra work to get it going before my package manager etc.
@rosstimson that's basically why I strive to have injected PATH. It doesn't work for whatever reasons in the latest version of macos (see #720). But that's the thing - PATH and other env variables must be set before Emacs attempts to use libgccjit.
Same issue.. MacOS 15.4.1 (24E263)
⛔ Error (use-package): emacs/:config: Native compiler error: (lambda (arg3 &optional) (let ((f #'yes-or-no-p)) (funcall f arg3))), "Compiling /Users/x/.emacs.d/eln-cache/30.1-cf025b42/subr--trampoline-7965732d6f722d6e6f2d70_yes_or_no_p_0.eln... ld: library 'emutls_w' not found libgccjit.so: error: error invoking gcc driver Internal native compiler error: "failed to compile", "/Users/x/.emacs.d/eln-cache/30.1-cf025b42/subr--trampoline-7965732d6f722d6e6f2d70_yes_or_no_p_0.eln", "error invoking gcc driver"
It's a bit disappointing that from the start, this Emacs distribution introduces friction on a brand new MacBook :( Is there something that we can do to anticipate the path?
Here is how I extracted the path in my case:
cat $(brew --cellar emacs-plus@30)/30.1/Emacs.app/Contents/Info.plist
Manually look for <key>PATH</key>, and then apply suggestions from @efroemling
Hack that helped me overcome this temporarily has been to set PATH within .emacs.d/early-init.el explicitly. I took the PATH variable value from the /opt/homebrew/opt/emacs-plus@30/Emacs.app/Contents/Info.plist and just set it like so:
;; TEMP: Explicitly set PATH environment variable and update exec-path to match it
;; otherwise emacs throws jit compilation errors
(setenv "PATH" "VALUEOFTHEPATH")
(setq exec-path (split-string (getenv "PATH") path-separator))
For some reason, without this explicit setenv, PATH within emacs was quite barebones for me.
EDIT: and I'm still subscribed to this issue so I can see if there's any alternative way to properly fix it :-D
I'm getting the same error, and the problem persists after trying most of the workarounds described above. I can help providing details if someone is actively working on this.
@d12frosted Hi, think I found a solution to fix this in general. I'm not a brew expert, but after a session with an LLM this was the output and it seems somewhat reasonable to me. Any thoughts on this? I imagine this will also fix https://github.com/d12frosted/homebrew-emacs-plus/issues/720
Alright, this is excellent! We have the exact code.
You've correctly identified that
inject_pathinEmacsBase.rbis the culprit, directly modifying theInfo.plistwithPlistBuddy. To fix this, we need to:
- Remove the
inject_pathcall from the[email protected]formula (and potentially other formula files if they exist for different Emacs versions).- Remove the
inject_pathdefinition fromEmacsBase.rb(as it's no longer needed).- Modify the
Emacs.app/Contents/MacOS/Emacswrapper script to source the user's shell environment.This is a BREAKING CHANGE in philosophy for the
emacs-plusformula, so be prepared to explain the rationale in your PR. The currentInfo.plistinjection is indeed outdated and brittle on modern macOS.Here's how to structure your PR:
Step 1: Modify
homebrew-emacs-plus/Formula/[email protected]Find the
installmethod. Locate and remove the line:# inject PATH to Info.plist inject_pathAfter removing that line, find the section where
bin/emacsis created (around line 143 in your provided code):# Replace the symlink with one that avoids starting Cocoa. (bin/"emacs").unlink # Kill the existing symlink (bin/"emacs").write <<~EOS #!/bin/bash exec #{prefix}/Emacs.app/Contents/MacOS/Emacs "$@" EOSThis section is for the
emacscommand-line alias. We're interested in theEmacs.app/Contents/MacOS/Emacsitself.Further down, where
prefix.install "nextstep/Emacs.app"occurs, is where the.appbundle is put in place. After this, we need to modify the internal wrapper script.Add the following code right after
prefix.install "nextstep/Emacs.app"and(prefix/"Emacs.app/Contents").install "native-lisp"in[email protected]:prefix.install "nextstep/Emacs.app" (prefix/"Emacs.app/Contents").install "native-lisp" # Patch the Emacs.app/Contents/MacOS/Emacs wrapper script to load the user's shell environment # This addresses the issue of GUI apps not inheriting PATH from the shell. # This replaces the brittle LSEnvironment injection. emacs_wrapper_script = "#{prefix}/Emacs.app/Contents/MacOS/Emacs" inreplace emacs_wrapper_script, /^#!/bin\/bash/, <<~EOS #!/bin/bash # Load user's shell profile to ensure correct PATH and other environment variables # This fixes issues with GUI Emacs.app not finding command-line tools. # Check for zsh profiles (common on macOS) if [ -f "$HOME/.zprofile" ]; then source "$HOME/.zprofile" elif [ -f "$HOME/.bash_profile" ]; then source "$HOME/.bash_profile" elif [ -f "$HOME/.zshrc" ]; then source "$HOME/.zshrc" elif [ -f "$HOME/.bashrc" ]; then source "$HOME/.bashrc" elif [ -f "$HOME/.profile" ]; then source "$HOME/.profile" fi # Ensure Homebrew's default paths are in PATH, as a fallback or for consistency. # This is especially important if user's shell profile doesn't correctly set Homebrew paths. if [ "$(uname -m)" = "arm64" ]; then export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH" else export PATH="/usr/local/bin:/usr/local/sbin:$PATH" fi # The original shebang line follows (now redundant but kept for clarity in the patch) EOS # Ensure the wrapper script is executable chmod 0755, emacs_wrapper_scriptExplanation of the Ruby
inreplace:
emacs_wrapper_script = "#{prefix}/Emacs.app/Contents/MacOS/Emacs": Defines the path to the wrapper script we want to modify.inreplace emacs_wrapper_script, /^#!/bin\/bash/, <<~EOS ... EOS: This is Homebrew's helper to perform an in-place replacement.
- The first argument (
emacs_wrapper_script) is the file to modify.- The second argument (
/^#!/bin\/bash/) is a regular expression matching the line to replace (the initial shebang#!/bin/bash).- The
<<~EOS ... EOSblock is a "heredoc" in Ruby, which allows you to define a multi-line string. This entire block will replace the matched shebang line.- Inside the heredoc, we put the bash script logic to source the user's environment and explicitly add Homebrew paths.
Step 2: Modify
homebrew-emacs-plus/Library/EmacsBase.rbLocate the
inject_pathmethod (around line 38 in your provided code) and delete the entire method:def inject_path ohai "Injecting PATH value to Emacs.app/Contents/Info.plist" app = "#{prefix}/Emacs.app" plist = "#{app}/Contents/Info.plist" path = PATH.new(ORIGINAL_PATHS) puts "Patching plist at #{plist} with following PATH value:" path.each_entry { |x| puts x } system "/usr/libexec/PlistBuddy -c 'Add :LSEnvironment dict' '#{plist}'" system "/usr/libexec/PlistBuddy -c 'Add :LSEnvironment:PATH string' '#{plist}'" system "/usr/libexec/PlistBuddy -c 'Set :LSEnvironment:PATH #{path}' '#{plist}'" system "/usr/libexec/PlistBuddy -c 'Print :LSEnvironment' '#{plist}'" system "touch '#{app}'" endAlso, update the
caveatsmethod to reflect the change:def caveats <<~EOS Emacs.app was installed to: #{prefix} To link the application to default Homebrew App location: osascript -e 'tell application "Finder" to make alias file to posix file "#{prefix}/Emacs.app" at posix file "/Applications" with properties {name:"Emacs.app"}' # Remove this line: Your PATH value was injected into Emacs.app/Contents/Info.plist # Replace it with something like: Your PATH is now loaded from your shell profile (~/.zprofile, ~/.bash_profile, etc.) when launching Emacs.app from Finder/Spotlight. Report any issues to https://github.com/d12frosted/homebrew-emacs-plus EOS end
Also something I've been facing, using the Doom Emacs distribution for what that's worth.
I've added the path from /opt/homebrew/opt/emacs-plus@30/Emacs.app/Contents/Info.plist to the top of my .config/emacs/early-init.el:
(setenv "PATH" "VALUEOFTHEPATH")
(setq exec-path (split-string (getenv "PATH") path-separator))
I thought it wasn't working, but I grep'd my .doom.d and found I'd been setting PATH in another way from an earlier fix attempt. All seems to work now
;; Temp: Explicitly set PATH environment variable and update exec-path to match it. ;; (the string here should be copied from the PATH in Emacs.app/Contents/Info.plist) (setenv "PATH" "/opt/homebrew/bin:/opt/homebrew/sbin:...etc etc...") (setq exec-path (split-string (getenv "PATH") path-separator))
@efroemling Thanks, this solution worked for me.
Some issue. have to disable native comp
(setq native-comp-deferred-compilation t)
(setq native-comp-async-report-warnings-errors nil)
can you try building from this branch - https://github.com/d12frosted/homebrew-emacs-plus/pull/841?
should be fixed with #841. let me know if the issue persists.