Solved How to start a Linux binary on FreeBSD, from within a ruby exec() statement?

On FreeBSD 13 AMD64 I have some Linux binaries (wkhtmltopdf in this case), who are running fine from a standard shell. But who fails to run from within a Ruby exec() statement.
  1. I am using Linux binaries because the FreeBSD builds for that specific package are broken.
  2. It is my understanding that FreeBSD is normally detecting the ELF file type and redirects all necessary files (like linked libraries) to /compat/linux/...
  3. This seems not to happen when run from within an exec() statement.
  4. The execution fails with:
    /usr/local/bin/wkhtmltopdf: error while loading shared libraries: /usr/local/lib/libpng16.so.16: ELF file OS ABI invalid
I unsuccessfully tried to start the command from /compat/linux/bin/bash -c '/usr/local/bin/wkhtmltopdf'

How could I proceed to make Ruby execute this binary in Linux emulation mode?
 
I just conveniently replaced the original broken FreeBSD binary with the Linux binary. I was not aware it mattered.
The binary now has been moved to /compat/linux/usr/bin, but the result is the same:
  1. From a normal shell it works fine.
  2. From the exec() method from Ruby, it does not find the Linux compatible libraries:
    /compat/linux/usr/bin/wkhtmltopdf_linux: error while loading shared libraries: /usr/local/lib/libpng16.so.16: ELF file OS ABI invalid
 
I was able to modify the Ruby exec() standard shell, from /bin/tcsh to /compat/linux/usr/bin/bash , by using: ENV['SHELL'] = '/compat/linux/usr/bin/bash'.

But the result is identical.

Somehow, FreeBSD is not parsing my binary through the Linuxalator.
 
I was able to resolve this by adding ENV['LD_LIBRARY_PATH'] = '/compat/linux/usr/lib64' before my exec() statement.
This adds the Linux library path to the set of paths used by the dynamic linker ld-elf.so.1 when searching for shared libraries.
 
Back
Top