bcardiff / crystal-fswatch

MIT License
16 stars 2 forks source link

Proper way to provide libfswatch on Ubuntu 20.04 #4

Closed paulocoghi closed 2 years ago

paulocoghi commented 2 years ago

After shards install, when trying to compile the Crystal code example provided on README, with:

crystal build src/liven.cr --release --no-debug

I'm getting the following error:

/usr/bin/ld: cannot find -lfswatch (this usually means you need to install the development package for libfswatch)
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc "${@}" -o /home/coghi/projects/liven/liven  -rdynamic -L/usr/bin/../lib/crystal -lfswatch -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` -lpcre -lm -lgc -lpthread -levent -lrt -ldl`

I'm on Ubuntu 20.04 and libfswatch-dev is not provided anymore (was provided up to 18.04), so the only package I was able to install was fswatch. But after installing it, the same error still occurs when trying to compile.

It seems that if I compile fswatch from source the problem will be solved, but I would like to provide Crystal libraries that use crystal-fswatch with no manual compilation needed from the user side.

Do you know if the libfswatch changed its name from Ubuntu version 20.04 onwards?


The shard.yml is:

name: liven
version: 0.1.0

authors:
  - Paulo Coghi <paulo@adimira.com>

dependencies:
  live_reload:
    github: bcardiff/live_reload.cr
  fswatch:
    github: bcardiff/crystal-fswatch

crystal: ">= 1.3.0"

license: MIT
paulocoghi commented 2 years ago

Looking on the details of fswatch package on Ubuntu 20.04, we can see it provides a shared library on

/usr/lib/x86_64-linux-gnu/libfswatch/libfswatch.so.11.0.1

But it doesn't seem to be found

bcardiff commented 2 years ago

Great. Things are a bit messy it seems.

  1. libfswatch-dev package was merged into fswatch package in some of the recent distros. As you mention, the https://packages.ubuntu.com/impish/amd64/fswatch/filelist includes the library.
  2. Crystal relies on pkg-config to find libraries. For that to work there should be a .pc file in a location known by pkg-config or at least include the location of the .pc file in the PKG_CONFIG_PATH.
  3. Unfortunately the fswatch package does not include such .pc file. See for example the contents of libgc-dev for a package that includes it.
  4. fswatch source code has all the needed pieces to create a .pc file, but a) that does not guarantees the linux packages will include that file. b) this was introduced in 1.15 ref

So, how we can make things work in ubuntu impish for example.

  1. Install the fswatch package
  2. Create a fswatch.pc file with the following content, this files could be in the working directory of your project.
Name: libfswatch
Description:
Version:
Libs: -L/usr/lib/x86_64-linux-gnu/libfswatch -lfswatch
  1. Put location of fswatch.pc in the PKG_CONFIG_PATH variable, assuming the .pc file is in your working directory that would be:export PKG_CONFIG_PATH=/path/to/project. With this you should be able to compile your app that depends on this shard.

But your app will not run probably. The libfswatch.so is a shared library in a non default location. If your app does not run with a message complaining that libfswatch was not found that means that LD_LIBRARY_PATH needs to be tweaked.

See how libfswatch is found by ldd after LD_LIBRARY_PATH is set.

$ ldd your_compiled_app
        linux-vdso.so.1 (0x00007ffcf2bdf000)
        libfswatch.so.11 => not found
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fa2ddd08000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa2ddc24000)
        libevent-2.1.so.7 => /lib/x86_64-linux-gnu/libevent-2.1.so.7 (0x00007fa2ddbce000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa2ddbb4000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa2dd98c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fa2ddfd0000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa2dd985000)

$ export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/libfswatch

$ ldd your_compiled_app  
        linux-vdso.so.1 (0x00007fff3eb0c000)
        libfswatch.so.11 => /usr/lib/x86_64-linux-gnu/libfswatch/libfswatch.so.11 (0x00007f80465f8000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f804657f000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f804649b000)
        libevent-2.1.so.7 => /lib/x86_64-linux-gnu/libevent-2.1.so.7 (0x00007f8046445000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f804642b000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8046203000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8046891000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f80461fc000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8045fe3000)

libfswatch seems to not have many users. People uses the app directly it seems. Using libraries with this state of the art distribution has it's hiccups unfortunately.

Some other considerations:

For additional help on how to deal with libraries in general use the forum were more wise people will probably collaborate.

paulocoghi commented 2 years ago

Thank you a lot, Brian!