nerves-project / nerves

Craft and deploy bulletproof embedded software in Elixir
http://nerves-project.org
Apache License 2.0
2.26k stars 193 forks source link

`lirc-tools`’s `default.so` plugin fails to load due to `undefined symbol: major` #974

Closed Cellane closed 5 months ago

Cellane commented 5 months ago

Preface

I’m not sure if this is the right place to report this problem, I’m sorry. I only started playing with Nerves three days ago and am not very skilled at Linux. Not sure if this is something for Nerves to fix or for upstream to fix, or if fixed in upstream, if we can just pull the changes, or something else entirely… I’ll appreciate any guidance as to how to proceed here 🙏

Environment

Current behavior

After creating a custom system that adds lirc-tools into userspace and enables infrared receiving and transmitting, and then altering config.txt to load a necessary device tree overlay, lirc fails to load its default plugin:

iex(1)> cmd "lirc-lsplugins"
# Driver            Flags Plugin
accent              ----  /usr/lib/lirc/plugins/accent.so
atwf83              ---L  /usr/lib/lirc/plugins/atwf83.so
audio_alsa          -a-L  /usr/lib/lirc/plugins/audio_alsa.so
bte                 ----  /usr/lib/lirc/plugins/bte.so
creative            ----  /usr/lib/lirc/plugins/creative.so
creative_infracd    ----  /usr/lib/lirc/plugins/creative_infracd.so
-                   F--   /usr/lib/lirc/plugins/default.so
# Error: /usr/lib/lirc/plugins/default.so: undefined symbol: major
devinput            ---L  /usr/lib/lirc/plugins/devinput.so
dsp                 -a--  /usr/lib/lirc/plugins/dsp.so
ea65                ----  /usr/lib/lirc/plugins/ea65.so
file                -as-  /usr/lib/lirc/plugins/file.so
girs                -asL  /usr/lib/lirc/plugins/girs.so
asusdh              ---L  /usr/lib/lirc/plugins/hiddev.so
bw6130              ---L  /usr/lib/lirc/plugins/hiddev.so
dvico               ---L  /usr/lib/lirc/plugins/hiddev.so
macmini             ---L  /usr/lib/lirc/plugins/hiddev.so
samsung             ---L  /usr/lib/lirc/plugins/hiddev.so
sb0540              ---L  /usr/lib/lirc/plugins/hiddev.so
sonyir              ---L  /usr/lib/lirc/plugins/hiddev.so
i2cuser             ----  /usr/lib/lirc/plugins/i2cuser.so
irlink              -a-L  /usr/lib/lirc/plugins/irlink.so
irtoy               -asL  /usr/lib/lirc/plugins/irtoy.so
livedrive_midi      ----  /usr/lib/lirc/plugins/livedrive_midi.so
livedrive_seq       ----  /usr/lib/lirc/plugins/livedrive_seq.so
logitech            ----  /usr/lib/lirc/plugins/logitech.so
mouseremote         ----  /usr/lib/lirc/plugins/mouseremote.so
mouseremote_ps2     ----  /usr/lib/lirc/plugins/mouseremote.so
mp3anywhere         ----  /usr/lib/lirc/plugins/mp3anywhere.so
mplay               ---L  /usr/lib/lirc/plugins/mplay.so
mplay2              ---L  /usr/lib/lirc/plugins/mplay.so
pcmak               ----  /usr/lib/lirc/plugins/pcmak.so
pinsys              ----  /usr/lib/lirc/plugins/pinsys.so
pixelview           ----  /usr/lib/lirc/plugins/pixelview.so
silitek             ----  /usr/lib/lirc/plugins/silitek.so
tira                --sL  /usr/lib/lirc/plugins/tira.so
tira_raw            -a-L  /usr/lib/lirc/plugins/tira.so
udp                 -a-L  /usr/lib/lirc/plugins/udp.so
uirt2               ----  /usr/lib/lirc/plugins/uirt2.so
uirt2_raw           -as-  /usr/lib/lirc/plugins/uirt2_raw.so
usb_uirt_raw        -as-  /usr/lib/lirc/plugins/uirt2_raw.so
usbx                ---L  /usr/lib/lirc/plugins/usbx.so
zotac               ---L  /usr/lib/lirc/plugins/zotac.so
#
#
# Flags:
# E:    Empty: Plugin loaded OK, but is empty (is this a plugin?).
# F:    Fail: Plugin failed to load (unresolved references?).
# a:    Any: Driver can be used with any remote or capture device.
# s:    Send: The driver can send data.
# L:    List: The driver can enumerate devices.
#1

This seems to be consistent with an issue reported here, showing the same undefined symbol: major error message.

It seems that the solution might be rather simple (as seen in the comments of the aforementioned issue), but I’m not sure how I’d introduce a custom patch to the custom system…

If I graciously stealborrow /usr/lib/arm-linux-gnueabihf/lirc/plugins/default.so from current version of Raspberry Pi OS for Raspberry Pi Zero W and place it in rootfs_overlay/usr/lib/lirc/plugins (the different path between the two systems is related to LIRC config), everything works perfectly, but I feel like this is somewhat hacky and the proper solution would be to fix the build, not replace the artefact.

iex(1)> cmd "lirc-lsplugins"
# Driver            Flags Plugin
accent              ----  /usr/lib/lirc/plugins/accent.so
atwf83              ---L  /usr/lib/lirc/plugins/atwf83.so
audio_alsa          -a-L  /usr/lib/lirc/plugins/audio_alsa.so
bte                 ----  /usr/lib/lirc/plugins/bte.so
creative            ----  /usr/lib/lirc/plugins/creative.so
creative_infracd    ----  /usr/lib/lirc/plugins/creative_infracd.so
default             ---L  /usr/lib/lirc/plugins/default.so
devinput            ---L  /usr/lib/lirc/plugins/devinput.so
dsp                 -a--  /usr/lib/lirc/plugins/dsp.so
(… snip…)

I tested both receiving and transmitting with this borrowed plugin and it works like a charm.

Expected behavior

lirc-tools should compile with all of its plugins being ready to be used.

fhunleth commented 5 months ago

Sorry - away this weekend and skimming your issue for now. The lirc patch that you found that includes sys/macros.h is the right fix. I wonder why that isn't upstream. The non-hack way would be to send the patch to the lirc repository so the lirc maintainers handle it. Buildroot and Nerves could patch it like Alpine does. It's just way better when upstream maintains it.

When I get back, I'll look more. Great issue write up!

fhunleth commented 5 months ago

I'm looking at this again. I think the right thing to do is to send a PR to https://sourceforge.net/projects/lirc/ and then wait for them to make a release so that the Buildroot maintainers can pull it in as a version bump.

However, I'm not sure how long that it will take for that patch to get merged or they could even reject it.

The most practical thing seems like it would be to create a patches directory in your Nerves system, set up Buildroot to look in it (via the nerves_config configuration file, and put a patch in there. See https://buildroot.org/downloads/manual/manual.html#_adding_project_specific_patches_and_hashes for the Buildroot instructions.

The other option to try if LiRC isn't being actively maintained is to submit the patch to Buildroot. I'm sure that the Buildroot maintainers will want to see that you tried submitting upstream first so that they're not on the hook for maintaining the patch. The good part is that Buildroot is really actively maintained, so getting a response from them doesn't require waiting as long usually.

Cellane commented 5 months ago

Thank you so much for looking into this! ❤️

I'll try reporting the issue back to LIRC folks (not sure if one can submit a PR to SourceForge projects, I had a quick look and didn't find any obvious way, but will look into it again) and if I don't get a response in a week or two (which seems likely as you mentioned, that project seems anything but alive…), I'll try talking to the Buildroot folks.

Thank you again! I think this issue can be closed then, since it ought to be fixed in a different place?

fhunleth commented 5 months ago

Thanks for trying with the LIRC and Buildroot folks.

I closed the issue, but if you run into a brick wall, I'll accept the patch in https://github.com/nerves-project/nerves_system_br.