2

I can't load packages in R because the file libpq.5.dylib is not in /usr/lib/libpq.5.dylib. It is in /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib

I tried this line: sudo ln -s /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib /usr/lib/libpq.5.dylib but I get this response: ln: /usr/lib/libpq.5.dylib: Operation not permitted

What can I do to get the file in /usr/lib/libpq.5.dylib without causing issues? This solution suggests that I may face problems down the line so I don't understand what to do.

MS Berends
  • 4,489
  • 1
  • 40
  • 53
gm007
  • 547
  • 4
  • 11

3 Answers3

4

You really don't want it in /usr/lib. Apple declared that as off-limits, and on newer macOS versions it lives on a read-only volume. Unless you're willing to go into recovery mode and manually tamper with the volume (and possibly repeat that on future OS updates), this is not the way to go.

Instead, let's address the core issue:
Dynamic libraries on macOS embed their own install path inside the binary, and the linker copies that into binaries linking against them. This information can be changed with install_name_tool (see man install_name_tool).

  1. Examine the install name of the dylib:

    otool -l /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib | fgrep -A2 LC_ID_DYLIB
    

    If the printed path already points to the dylib itself (or a path that is symlinked to it), use this path as [new_path] below, and skip step 2.

  2. If the dylib's install name does not point back to itself, run this:

    sudo install_name_tool -id /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib
    

    And use /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib for [new_path] below.

  3. For binaries that link against the dylib, run:

    sudo install_name_tool -change /usr/lib/libpq.5.dylib [new_path] [path_to_binary]
    
Siguza
  • 21,155
  • 6
  • 52
  • 89
  • I'm not sure about the binary path. I'm not clear on 3. This is the error I see in R: Error: package or namespace load failed for ‘tidycensus’ in dyn.load(file, DLLpath = DLLpath, ...): unable to load shared object '/Library/Frameworks/R.framework/Versions/4.0/Resources/library/sf/libs/sf.so': dlopen(/Library/Frameworks/R.framework/Versions/4.0/Resources/library/sf/libs/sf.so, 6): Library not loaded: /usr/lib/libpq.5.dylib Referenced from: /Library/Frameworks/R.framework/Versions/4.0/Resources/library/sf/libs/sf.so Reason: image not found – gm007 Oct 09 '20 at 01:04
  • 1
    Then the binary you want to edit is `/Library/Frameworks/R.framework/Versions/4.0/Resources/library/sf/libs/sf.so`. – Siguza Oct 09 '20 at 01:37
  • so step 3 is: sudo install_name_tool -change /usr/lib/libpq.5.dylib /usr/local/Cellar/libpq/13.0/lib/libpq.5.dylib/Library/Frameworks/R.framework/Versions/4.0/Resources/library/sf/libs/sf.so – gm007 Oct 09 '20 at 01:38
  • Many thanks! Works flawlessly. This happens every time I update to a new major R version and have to install all packages again, such as `sf` (on macOS). – MS Berends Oct 21 '20 at 11:29
  • I always getting usage error - sudo install_name_tool -change /usr/local/Cellar/libpq/14.2/lib/libpq.5.dylib /usr/lib/libpq.5.dylib Usage: /Library/Developer/CommandLineTools/usr/bin/install_name_tool [-change old new] ... [-rpath old new] ... [-add_rpath new] ... [-delete_rpath old] ... [-id name] input – thedevd Mar 01 '22 at 14:53
  • @thedevd you only gave it two arguments. You need a third. – Siguza Mar 01 '22 at 17:45
  • @Siguza, can you please provide me the example because this is so confusing. So I have the libpq.5.dylib in the location /usr/local/Cellar/postgresql/14.2_1/lib/libpq.5.dylib. so how do I link in a way that it should be available from path /usr/lib/libpq.5.dylib – thedevd Mar 03 '22 at 07:18
  • @thedevd I think in your case you want `-id` and not `-change`? – Siguza Mar 05 '22 at 19:56
0

I had the same issue building a container through docker for API use : RPostgres was installed but the library couldn't load, same error message. Since I had installed Postgres on my machine, I figure the problem was worked around therefore I had no such message on local ; but here's how I solved this in my dockerfile, 100% verified on a machine with nothing related to R installed :

RUN apt-get update && apt-get install libpq5 -y

So executing apt-get update && apt-get install libpq5 -y on your terminal should do the trick. Light and efficient.

0

It tried to load libpq.5.dylib from the symlink /opt/homebrew/opt/postgresql/lib/libpq.5.dylib but could not find the file, so you need to update it:

# TODO: get this from the error, after "Library not loaded:"
SYMLINK_PATH="/opt/homebrew/opt/postgresql/lib/libpq.5.dylib"

# TODO: find this in your machine. The version maybe different than mine
DESTINATION_PATH="/opt/homebrew/opt/postgresql/lib/postgresql@14/libpq.5.dylib"

sudo mv $SYMLINK_PATH $SYMLINK_PATH.old
sudo ln -s $DESTINATION_PATH $SYMLINK_PATH