Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need to set LIBRARY_PATH for emacs-plus@28 with --with-native-comp #378

Closed
poldy opened this issue Aug 4, 2021 · 29 comments
Closed

Need to set LIBRARY_PATH for emacs-plus@28 with --with-native-comp #378

poldy opened this issue Aug 4, 2021 · 29 comments

Comments

@poldy
Copy link

poldy commented Aug 4, 2021

I ran brew install emacs-plus@28 --with-native-comp and it completed successfully. However, when I tried to run Emacs although the editor worked, there were loads of native compilation warnings.

The solution was to create a one-line ~/.emacs.d/early-init.el, with the following contents:

(setenv "LIBRARY_PATH" "/opt/homebrew/lib/gcc/11:/opt/homebrew/lib/gcc/11/gcc/aarch64-apple-darwin20/11.1.0")

I'd suggest adding this to the "gccemacs" section of the README.

This is on an M1 iMac, it works great now.

@jilen
Copy link

jilen commented Aug 19, 2021

Start emacs from the Terminal instead of click the emacs icon works for me.

@kommen
Copy link
Contributor

kommen commented Aug 21, 2021

EDIT

Don't set LIBRARY_PATH as I originally suggested in this post, it is just fighting symptoms, not the root cause, see other comments below.

Original comment below
------------------------

I can confirm setting LIBRARY_PATH as @poldy suggests as an env in my bash/zsh config fixes native-comp errors. Without it set I got this (a bit redacted)

Native compiler error: (lambda (&optional arg6) (let ((f #'kill-emacs)) (funcall f arg6))), Compiling <home>/.emacs.d/eln-cache/28.0.50-b1d099bb/subr--trampoline-6b696c6c2d656d616373_kill_emacs_0.eln...
ld: library not found for -lgcc_s.1.1
libgccjit.so: error: error invoking gcc driver
Debugger entered--Lisp error: (native-ice "failed to compile" "<home>/emacs.d/eln-cache/28.0.50-b1d099bb/..." "error invoking gcc driver")

@d12frosted
Copy link
Owner

d12frosted commented Aug 21, 2021

See this message. If you have to set LIBRARY_PATH that probably just means something is wrong with your environment. Works for me without any hacks like this. Though I must admit, never tested on M1.

@kommen
Copy link
Contributor

kommen commented Aug 21, 2021

@d12frosted thanks!

After reinstalling gcc and libgccjit (also from source) with no success, I poked around in my env:

It seems the issue was Spacemacs caching the env variables (including PATH) in the .spacemacs.env file. After adjusting the PATH there to include my newish homebrew M1 setup's /opt/homebrew/bin:/opt/homebrew/sbin: it looks I only get one native comp error regarding cl-lib, the other files now seem to compile fine.

@d12frosted
Copy link
Owner

it looks I only get one native comp error regarding cl-lib

Do you mean an error saying that it's obsolete/deprecated? 😄

the other files now seem to compile fine.

This sounds great.

@kommen
Copy link
Contributor

kommen commented Aug 22, 2021

Do you mean an error saying that it's obsolete/deprecated? 😄

Unfortunately no 😅. Still some native-comp error:

Compiling /opt/homebrew/Cellar/emacs-plus@28/28.0.50/share/emacs/28.0.50/lisp/emacs-lisp/cl-lib.el.gz...
uncompressing cl-lib.el.gz...
uncompressing cl-lib.el.gz...done
ld: library not found for -lgcc_s.1.1
libgccjit.so: error: error invoking gcc driver
/opt/homebrew/Cellar/emacs-plus@28/28.0.50/share/emacs/28.0.50/lisp/emacs-lisp/cl-lib.el.gz: Error: Internal native compiler error failed to compile

The others following immediately after it seemingly work:

Compiling /opt/homebrew/Cellar/emacs-plus@28/28.0.50/share/emacs/28.0.50/lisp/emacs-lisp/seq.el.gz...
uncompressing seq.el.gz...
uncompressing seq.el.gz...done
Compiling /opt/homebrew/Cellar/emacs-plus@28/28.0.50/share/emacs/28.0.50/lisp/emacs-lisp/gv.el.gz...
uncompressing gv.el.gz...
uncompressing gv.el.gz...done
...

@kommen
Copy link
Contributor

kommen commented Aug 23, 2021

I also got that last error fixed: it was because the compilation was kicked off by spacemacs before loading the .spacemacs.env file. This happens because when starting Emacs.app from the macOS Finder or Dock, the env vars are different then when launching from the command line (where I have my .zshrc). Launching Emacs from the commandline (executing /Applications/Emacs.app/Contents/MacOS/Emacs directly) so it inherits the env vars from there fixed it.

So I can confirm that these errors were entirely due to my environment Emacs runs in not being set up properly, especially that PATH is set correctly for Emacs when running with homebrew on an M1 Mac. I hope this helps other folks running into this.

@d12frosted
Copy link
Owner

People say that null pointers are billion dollars issue, but I'd rather say that it's PATH. I actually wonder if it's a good idea to patch info.plist file when emacs-plus is built so it includes PATH value during the build. That way it will automatically get the right (though possible out of date) PATH value without the need to resort to things like exec-path-from-shell or env from Spacemacs.

@elken
Copy link
Contributor

elken commented Sep 1, 2021

People say that null pointers are billion dollars issue, but I'd rather say that it's PATH. I actually wonder if it's a good idea to patch info.plist file when emacs-plus is built so it includes PATH value during the build. That way it will automatically get the right (though possible out of date) PATH value without the need to resort to things like exec-path-from-shell or env from Spacemacs.

This is probably a better solution IMO than relying on users having correct environments. When built with native-comp, add the path during build so on startup the compiler can find libgccjit.

@eltone
Copy link

eltone commented Sep 3, 2021

I had the same error after brew reinstall emacs-plus@28 --with-native-comp. I was able to fix it with:

brew unlink emacs-plus@28 && brew link emacs-plus@28

@d12frosted
Copy link
Owner

d12frosted commented Sep 3, 2021 via email

@gwbrown
Copy link

gwbrown commented Sep 8, 2021

In case anyone else finds this wants to change Info.plist fix manually after compiling, I found details on how to do so on this EmacsWiki page. Note that after editing Info.plist, you need to run /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f <path_to_your_Emacs.app> or MacOS won't pick up on the fact that the plist has been updated and won't get the changed environment variables.

(That last bit had me pulling my hair out for a while)

@yuezhu
Copy link

yuezhu commented Oct 6, 2021

On macOS 10.15 I was getting the same error while launching the Emacs application from the LaunchPad/Dock. It turned out the PATH environment variable isn't set correctly in this case. And I was able to work it around by adding the PATH into /usr/local/opt/emacs-plus@28/Emacs.app/Contents/Info.plist as follows:

# /usr/libexec/PlistBuddy -c "Add :LSEnvironment dict" /usr/local/opt/emacs-plus@28/Emacs.app/Contents/Info.plist
# /usr/libexec/PlistBuddy -c "Add :LSEnvironment:PATH string" /usr/local/opt/emacs-plus@28/Emacs.app/Contents/Info.plist
# /usr/libexec/PlistBuddy -c "Set :LSEnvironment:PATH $(echo "$PATH")" /usr/local/opt/emacs-plus@28/Emacs.app/Contents/Info.plist
# /usr/libexec/PlistBuddy -c "Print :LSEnvironment" /usr/local/opt/emacs-plus@28/Emacs.app/Contents/Info.plist
# touch /usr/local/opt/emacs-plus@28/Emacs.app

Make sure that the PATH environment variable is set correctly in your shell.

@DivineDominion
Copy link

DivineDominion commented Nov 10, 2021

On M1 Macs, the path to all Homebrew stuffs is different.

I'd suggest brew --prefix --installed emacs-plus@28 instead, so the calls become:

/usr/libexec/PlistBuddy -c "Add :LSEnvironment dict" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :LSEnvironment:PATH string" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Set :LSEnvironment:PATH $(echo "$PATH")" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Print :LSEnvironment" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
touch `brew --prefix --installed emacs-plus@28`/Emacs.app

Without these fixes, I have to launch Emacs from the shell. Otherwise it just won't find libgccjit etc. during native compilation

Edit: Shorter

alias pbd=/usr/libexec/PlistBuddy
export emacsapp=`brew --prefix --installed emacs-plus@28`/Emacs.app
export infoplist="${emacsapp}/Contents/Info.plist"

pbd -c "Add :LSEnvironment dict" "${infoplist}"
pbd -c "Add :LSEnvironment:PATH string" "${infoplist}"
pbd -c "Set :LSEnvironment:PATH $(echo "$PATH")" "${infoplist}"
pbd -c "Print :LSEnvironment" "${infoplist}"
touch ${emacsapp}

@jimeh
Copy link

jimeh commented Nov 11, 2021

Not sure if it's all that helpful, but I mess about with the LIBRARY_PATH environment variable with my custom build script that attempts to produce a fully self-contained Emacs.app. Because it copies gcc and libgccjit stuff into the .app bundle, I need to point LIBRARY_PATH at the specific directories within the bundle.

Potentially emacs-plus can do something similar, by simply ensuring it's pointing at the correct brew paths.

In my case, I add some custom elisp to Emacs.app/Contents/Resources/lisp/site-start.el, which if it exists, is loaded before both init.el and early-init.el from user config.

For reference, this is what the elisp my build-script produces looks like:

;; Set LIBRARY_PATH to point at bundled GCC and Xcode Command Line Tools to
;; ensure native-comp works.
(when (and (eq system-type 'darwin)
           (string-match-p "\.app\/Contents\/MacOS\/?$"
                           invocation-directory))
  (let* ((library-path-env (getenv "LIBRARY_PATH"))
         (devtools-dir
          "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib")
         (gcc-dir (expand-file-name
                   "lib/lib/gcc/11"
                   invocation-directory))
         (darwin-dir (expand-file-name
                      "lib/lib/gcc/11/gcc/x86_64-apple-darwin19/11_2_0"
                      invocation-directory))
         (lib-paths (list)))

    (if library-path-env
        (push library-path-env lib-paths))
    (if (file-directory-p devtools-dir)
        (push devtools-dir lib-paths))
    (push darwin-dir lib-paths)
    (push gcc-dir lib-paths)

    (setenv "LIBRARY_PATH" (mapconcat 'identity lib-paths ":"))))

The above obviously won't work as is in an emacs-plus Emacs.app bundle, but it could potentially be adjusted to detect/find or just hard-code the relevant homebrew paths for GCC.

@jsmestad
Copy link

On M1 Macs, the path to all Homebrew stuffs is different.

I'd suggest brew --prefix --installed emacs-plus@28 instead, so the calls become:

/usr/libexec/PlistBuddy -c "Add :LSEnvironment dict" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :LSEnvironment:PATH string" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Set :LSEnvironment:PATH $(echo "$PATH")" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Print :LSEnvironment" `brew --prefix --installed emacs-plus@28`/Emacs.app/Contents/Info.plist
touch `brew --prefix --installed emacs-plus@28`/Emacs.app

Without these fixes, I have to launch Emacs from the shell. Otherwise it just won't find libgccjit etc. during native compilation

Edit: Shorter

alias pbd=/usr/libexec/PlistBuddy
export emacsapp=`brew --prefix --installed emacs-plus@28`/Emacs.app
export infoplist="${emacsapp}/Contents/Info.plist"

pbd -c "Add :LSEnvironment dict" "${infoplist}"
pbd -c "Add :LSEnvironment:PATH string" "${infoplist}"
pbd -c "Set :LSEnvironment:PATH $(echo "$PATH")" "${infoplist}"
pbd -c "Print :LSEnvironment" "${infoplist}"
touch ${emacsapp}

This worked great for me. Thank you 🙏

@tilgovi
Copy link

tilgovi commented Mar 23, 2022

This appears to have worked for me, as well, on an Intel mac.

@jsmestad
Copy link

@d12frosted would it make sense to add this to the main script? I have to manually apply this fix to every install on my M1 mac or launching from macOS launcher has not found errors

@d12frosted
Copy link
Owner

@jsmestad in general, it's a bad idea to modify LIBRARY_PATH and other things like this. This simply means that something is wrong in the environment. See #378 (comment).

The only place where it's valid (IMHO) is Emacs.app own Info.plist file. I have an idea of injecting several environment variables into Info.plist file to avoid plethora of issues people run into when running Emacs.app due to how macOS works. This includes, but is not limited to PATH and LIBRARY_PATH. This will not affect running emacs from terminal as it will simply inherit interactive session. I just need to find some time to play around with this idea. Maybe next week? 🤷

WDYT @jsmestad ?

@jsmestad
Copy link

Yeah I agree. Interested to see how you approach it!

The macOS launcher issue has been hurting folks adopting Emacs, at least at my office, because they think it's too difficult/buggy to get native-comp working when in-fact this has nothing to do with native-comp. 🫤

d12frosted added a commit that referenced this issue Apr 25, 2022
The core issue here is environment in which
macOS starts applications from Finder/Docker/Spotlight/etc. This
change mostly helps users of `native-comp` feature (e.g. #378), but
it also should help other users as well ([see this comment][1])

[1]: #414 (comment)
@d12frosted
Copy link
Owner

@jsmestad started toying around with this idea in #453. It was not obvious how to get real user PATH instead of one from brew env.

For now doing it for emacs-plus@29 only.

Right now the build is red because GitHub packages degraded according to https://www.githubstatus.com

Screenshot 2022-04-25 at 13 37 30

In any case, I would love someone to test it 🙏

@d12frosted
Copy link
Owner

Ok, it's green now. So I would appreciate some testing. In case no one reports issues till Wednesday, I will merge it :)

@aaronjensen
Copy link
Contributor

Worked for me!

@tilgovi
Copy link

tilgovi commented Apr 26, 2022

emacs-plus@29 --with-native-comp working fine for me, too, with no plist hacking.

d12frosted added a commit that referenced this issue Apr 27, 2022
The core issue here is environment in which
macOS starts applications from Finder/Docker/Spotlight/etc. This
change mostly helps users of `native-comp` feature (e.g. #378), but
it also should help other users as well ([see this comment][1])

[1]: #414 (comment)
@d12frosted
Copy link
Owner

Merged #453, which should ease usage of native compilation feature. Please let me know if you still encounter any issues.

@jsmestad
Copy link

@d12frosted sorry for the delay. The patch works great. Thanks!

@d12frosted
Copy link
Owner

@jsmestad glad to hear :)

@sainathadapa
Copy link

sainathadapa commented Aug 5, 2023

Just in case it helps anyone in the future, after quite a bit of trial and error, the following steps worked:

Uninstalled gcc and libgccjit

brew uninstall --ignore-dependencies libgccjit

Uninstalled any existing emacs-plus installations

brew uninstall emacs-plus@29

Installed libgccjit from source

brew install --build-from-source libgccjit

Unlinked and relinked libgccjit

brew unlink libgccjit && brew link libgccjit

Installed emacs-plus

brew install emacs-plus@29 --with-native-comp --with-imagemagick --with-no-frame-refocus

Added the following statement to .emacs.d/init.el

(setenv "LIBRARY_PATH"
	(mapconcat 'identity
	 '(
       "/usr/local/Cellar/gcc/13.1.0/lib/gcc/13/"
       "/usr/local/Cellar/libgccjit/13.1.0/lib/gcc/13/"
       "/usr/local/Cellar/gcc/13.1.0/lib/gcc/13/gcc/x86_64-apple-darwin22/13/"
       "/opt/homebrew/opt/gcc/lib/gcc/13"
       "/opt/homebrew/opt/libgccjit/lib/gcc/13"
       "/opt/homebrew/opt/gcc/lib/gcc/13/gcc/aarch64-apple-darwin22/13")
         ":"))

@vintonc
Copy link

vintonc commented Jun 12, 2024

I had this issue today after "sudo port upgrade outdated" on Monterey MacOS 12.7.5 on a 2015 MBP.
I tried everything here and anywhere else I could find. What ended up working for me was
"rm -rf /Library/Developer/CommandLineTools" to delete the command line tools directory and then reinstalling them
"xcode-select --install" this pops up a dialog asking to reinstall. It tool almost 20 minutes to reinstall

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests