MicroPost: Install "ueberzug" on MacOS
Published: 2022-07-17 20:09:27

Today I discovered the https://github.com/d0c-s4vage/lookatme repository and thought the project was really cool! Sure there's some security implications with the "terminal" extension (among other things), but if you know what you're doing, the tool is really interesting :-)

Trying to install it however, was a bit of a pain. I only really cared about the `image_ueberzug` extension, so that's the main one I wanted to install, however, installing it wouldn't work!

```
$ pip install lookatme.contrib.image_ueberzug
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Collecting ueberzug
  Using cached ueberzug-18.1.9.tar.gz (36 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: python-xlib in /usr/local/lib/python3.9/site-packages (from ueberzug) (0.31)
Requirement already satisfied: pillow in /usr/local/lib/python3.9/site-packages (from ueberzug) (9.2.0)
Requirement already satisfied: docopt in /usr/local/lib/python3.9/site-packages (from ueberzug) (0.6.2)
Requirement already satisfied: attrs>=18.2.0 in /usr/local/lib/python3.9/site-packages (from ueberzug) (21.4.0)
Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.9/site-packages (from python-xlib->ueberzug) (1.16.0)
Building wheels for collected packages: ueberzug
  Building wheel for ueberzug (setup.py): started
  Building wheel for ueberzug (setup.py): finished with status 'error'
  error: subprocess-exited-with-error
  
  × python setup.py bdist_wheel did not run successfully.
  │ exit code: 1
  ╰─> [51 lines of output]
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.macosx-12-x86_64-cpython-39
      creating build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/scaling.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/tmux_util.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/files.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/xutil.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/loading.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/thread.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/version.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/library.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/terminal.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/ui.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/batch.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/conversion.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/__init__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/pattern.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/query_windows.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/action.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/parser.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/geometry.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/layer.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/process.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/__main__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      creating build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib
      copying ueberzug/lib/__init__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib
      creating build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib/v0
      copying ueberzug/lib/v0/__init__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib/v0
      running egg_info
      writing ueberzug.egg-info/PKG-INFO
      writing dependency_links to ueberzug.egg-info/dependency_links.txt
      writing entry points to ueberzug.egg-info/entry_points.txt
      writing requirements to ueberzug.egg-info/requires.txt
      writing top-level names to ueberzug.egg-info/top_level.txt
      reading manifest file 'ueberzug.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      writing manifest file 'ueberzug.egg-info/SOURCES.txt'
      copying ueberzug/lib/lib.sh -> build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib
      running build_ext
      building 'Xshm' extension
      creating build/temp.macosx-12-x86_64-cpython-39
      creating build/temp.macosx-12-x86_64-cpython-39/Xshm
      clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk -I/usr/local/opt/node@10/include -I/usr/local/opt/python@3.9/Frameworks/Python.framework/Versions/3.9/include/python3.9 -c Xshm/Xshm.c -o build/temp.macosx-12-x86_64-cpython-39/Xshm/Xshm.o
      Xshm/Xshm.c:5:10: fatal error: 'X11/Xlib.h' file not found
      #include <X11/Xlib.h>
               ^~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for ueberzug
  Running setup.py clean for ueberzug
Failed to build ueberzug
Installing collected packages: ueberzug
  DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
  Running setup.py install for ueberzug: started
  Running setup.py install for ueberzug: finished with status 'error'
  error: subprocess-exited-with-error
  
  × Running setup.py install for ueberzug did not run successfully.
  │ exit code: 1
  ╰─> [53 lines of output]
      running install
      /usr/local/lib/python3.9/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        warnings.warn(
      running build
      running build_py
      creating build
      creating build/lib.macosx-12-x86_64-cpython-39
      creating build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/scaling.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/tmux_util.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/files.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/xutil.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/loading.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/thread.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/version.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/library.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/terminal.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/ui.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/batch.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/conversion.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/__init__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/pattern.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/query_windows.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/action.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/parser.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/geometry.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/layer.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/process.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      copying ueberzug/__main__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug
      creating build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib
      copying ueberzug/lib/__init__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib
      creating build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib/v0
      copying ueberzug/lib/v0/__init__.py -> build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib/v0
      running egg_info
      writing ueberzug.egg-info/PKG-INFO
      writing dependency_links to ueberzug.egg-info/dependency_links.txt
      writing entry points to ueberzug.egg-info/entry_points.txt
      writing requirements to ueberzug.egg-info/requires.txt
      writing top-level names to ueberzug.egg-info/top_level.txt
      reading manifest file 'ueberzug.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      writing manifest file 'ueberzug.egg-info/SOURCES.txt'
      copying ueberzug/lib/lib.sh -> build/lib.macosx-12-x86_64-cpython-39/ueberzug/lib
      running build_ext
      building 'Xshm' extension
      creating build/temp.macosx-12-x86_64-cpython-39
      creating build/temp.macosx-12-x86_64-cpython-39/Xshm
      clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk -I/usr/local/opt/node@10/include -I/usr/local/opt/python@3.9/Frameworks/Python.framework/Versions/3.9/include/python3.9 -c Xshm/Xshm.c -o build/temp.macosx-12-x86_64-cpython-39/Xshm/Xshm.o
      Xshm/Xshm.c:5:10: fatal error: 'X11/Xlib.h' file not found
      #include <X11/Xlib.h>
               ^~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> ueberzug

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.
```

That's a pretty large error message! But the important part is towards the bottom:
```
      Xshm/Xshm.c:5:10: fatal error: 'X11/Xlib.h' file not found
      #include <X11/Xlib.h>
               ^~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
```

Did a lot of Googling and eventually found that you can pass build parameters to the `pip` command... cool! You learn something new everyday!

Long story short, I had to pass two additional parameters:
1. `-I/usr/local/include`
2. `-L/usr/X11/lib`

This gave me the following `pip install` command:
```
pip install \
  --global-option=build_ext \
  --global-option="-I/usr/local/include" \
  --global-option="-L/opt/X11/lib"  \
  lookatme.contrib.image_ueberzug
```

But this wasn't enough! Upon trying to run the `ueberzug` executable, I got a "command not found" error!!

Yet another long story short... had to run this to set it up:
```
$ ln -s $(find /usr/local/Cellar -name ueberzug) /usr/local/bin/ueberzug
```

To summarize my adventure... here's a short script that'll do the above in a single run:
```
$ cat install.lookatme-contrib.sh
#!/bin/zsh

pip install \
  --global-option=build_ext \
  --global-option="-I/usr/local/include" \
  --global-option="-L/opt/X11/lib"  \
  lookatme.contrib.image_ueberzug

[[ -x "$(command -v ueberzug)" ]] || {
  echo "Locating 'ueberzug' executable to set up soft-link ..."
  ln -s $(find /usr/local/Cellar -name ueberzug) /usr/local/bin/ueberzug
}

echo "\nDone"
```

^^^ For the above script, the `[[ -x "$(command -v <cmd>)" ]]` part checks to see if the shell can find the specified command.

Found how to do that here: https://stackoverflow.com/questions/592620/how-can-i-check-if-a-program-exists-from-a-bash-script

Praise StackOverFlow!! :P