Creating appimage for OpenModelica: File not found error (binary patching needed?)


#1

I am building an appimage of OpenModelica which is initially quite easy since it is available as a deb-repository.

See my receipe here: https://github.com/gntech/AppImages/blob/add-openmodelica-receipe/recipes/OpenModelica.yml

The appimage builds fine but when I start the app and open “Tools/OpenModelica Compiler CLI” I get the following error message:

Error: File not Found: /usr/lib/omc/ModelicaBuiltin.mo.

However when I extract the appimage into a folder I can see that file is at the location it should be. I suspect that this has something to do with absolute vs relative search paths?

As you can see in my recipe I have tried the following attempt at binary patching (inspired from the FreeCAD recipe) But it does not work.

- find usr/ -type f -exec sed -i -e "s@/usr/lib/omc@././/usr/lib/omc@g" {} \;

#2

Best is not to use absolute paths to load resources, but paths relative to the main binary.

If you want to go patch pre-existing binaries: Please do not put usr in the replacement, like in the examples. When the AppImage is executed, we do a chdir() into usr/ in the AppImage.


#3

Which btw isn’t well documented. :wink:

Don’t want to hijack the thread, but what’s the rationale behind switching to usr/?


#4

The payload application binary must not contain any hardcoded paths that would prevent it from being relocatable. You can check this by running strings MyApp.AppDir/usr/bin/myapp | grep /usr. Should this return something, then you need to modify your app programmatically (i.e., by changing the source code).

If you prefer not to change the source code of your app and/or would not like to recompile your app, you can also patch the binary, for example using the command sed -i -e 's|/usr|././|g' MyApp.AppDir/usr/bin/myapp. To make this kind of binary patching possible, AppRun.c does a chdir() into usr/ in the AppImage prior to executing the main payload application.


#5

Ok let me rephrase this to make sure I got it right:

Patching only just works, because /usr and ././ has the same length. Otherwise it would screw up the binary. Replacing /usr by usr or ./usr is therefore not possible. That’s why we want to be in usr/ and not in the AppDir’s root.


#6

Exactly. This is correct.