Packaging i386 32bit binary in AMD64 snap

Hi All,
My first attempt on snapping. Trying to figure out how to properly package 32bit binary and libs into AMD64 snap. I am trying to package a old 32bit game called “opensonic” into AMD64 snap. The game works reasonably fine in 64bit system if i386 architecture is enabled. I have tested it on 16.04 AMD64 and 18.04 AMD64 systems.

I have checked the following discussions. From what I understand I can use a new section in “parts” to enable i386 at build vm using dpkg --add-architecture i386. What I am wondering is what can I do so the sanpd enable architecture i386 when user installs this snap?


so far this is how my snapcraft.yaml looks like.

name: opensonic 
base: core18 
version: '0.1' 
summary: opensonic 
description: |
    A game inspired by Sonic. Similar to Opensurge.
grade: devel 
confinement: devmode 

parts:
    enable-i386:
        plugin: nil
        prepare: |
            dpkg --add-architecture i386
            apt-get update

    opensonic:
        plugin: dump
        source: opensnc-bin/

apps:
    opensonic:
        command: opensonic

this is how the files and directory structures looks like.
~/snapcraft/opensnc/opensnc-bin$ tree
.
├── config
│ └── samples.def
├── icon.png
├── images
│ ├── acts.png
│ ├── animals.png
│ ├── baddies.png
│ ├── boss.png
│ ├── bumper.png
│ ├── checkpoint_orb.png
│ ├── desert1.png
│ ├── dnadoors.png
│ ├── editorbg.png
│ ├── even_more_shields.png
│ ├── font.png
│ ├── gui.png
│ ├── intro.png
│ ├── island2.png
│ ├── island3.png
│ ├── island.png
│ ├── item_boxes.png
│ ├── items.png
│ ├── lady_bugsy.png
│ ├── more_shields.png
│ ├── null.png
│ ├── ocean2.png
│ ├── oceanfg.png
│ ├── ocean.png
│ ├── player.png
│ ├── prototype1.png
│ ├── prototype2.png
│ ├── quest_extra.png
│ ├── questionmark.png
│ ├── quest_superbosses.png
│ ├── quest_tutorial.png
│ ├── ring_shields.png
│ ├── sourcecode.png
│ ├── special.png
│ ├── spikes.png
│ ├── spring_pads.png
│ ├── squarebg.png
│ ├── switches.png
│ ├── template2.png
│ ├── template3.png
│ ├── template.png
│ └── title.png
├── languages
│ ├── deutsch.lng
│ ├── dutch.lng
│ ├── english.lng
│ ├── francais.lng
│ ├── indonesian.lng
│ ├── italiano.lng
│ ├── polish.lng
│ └── ptbr.lng
├── levels
│ ├── blue_ocean_1.lev
│ ├── blue_ocean_2.lev
│ ├── blue_ocean_3.lev
│ ├── desert1.lev
│ ├── exotic_1.lev
│ ├── exotic_2.lev
│ ├── exotic_3.lev
│ ├── exotichell_1.lev
│ ├── prototype.lev
│ ├── superboss_1.lev
│ ├── superboss_2.lev
│ ├── template.lev
│ ├── testzone.lev
│ ├── tutorial_1.lev
│ └── tutorial_2.lev
├── liballeg.so.4.4
├── libICE.so.6
├── libogg.so.0
├── libpng12.so.0
├── libSM.so.6
├── libuuid.so.1
├── libvorbisfile.so.3
├── libvorbis.so.0
├── libX11.so.6
├── libXau.so.6
├── libxcb.so.1
├── libXcursor.so.1
├── libXdmcp.so.6
├── libXext.so.6
├── libXfixes.so.3
├── libXpm.so.4
├── libXrender.so.1
├── libXxf86vm.so.1
├── libz.so.1
├── licenses
│ ├── 2xsai.txt
│ ├── Allegro.txt
│ ├── DUMB.txt
│ ├── jpgalleg.txt
│ ├── loadpng.txt
│ ├── logg.txt
│ └── nanoparser.txt
├── license.txt
├── logfile.txt
├── musics
│ ├── boss.ogg
│ ├── credits.txt
│ ├── crusader.ogg
│ ├── invincible.ogg
│ ├── luminous_vein.ogg
│ ├── options.ogg
│ ├── speed.ogg
│ └── title.ogg
├── objects
│ └── old_enemies.obj
├── opensonic
├── opensonic_bin
├── quests
│ ├── default.qst
│ ├── extra.qst
│ ├── superbosses.qst
│ └── tutorial.qst
├── readme.html
├── readme_it.html
├── samples
│ ├── 1up.ogg
│ ├── acidshield.wav
│ ├── bigring.wav
│ ├── bigshot.wav
│ ├── bosshit.wav
│ ├── brake.wav
│ ├── break.wav
│ ├── bumper.wav
│ ├── cash.wav
│ ├── checkpoint.wav
│ ├── choose.wav
│ ├── credits.txt
│ ├── death.wav
│ ├── deny.wav
│ ├── destroypop.wav
│ ├── door1.wav
│ ├── door2.wav
│ ├── endsign.wav
│ ├── fire2.wav
│ ├── fireshield.wav
│ ├── fire.wav
│ ├── floorfall.wav
│ ├── glasses.wav
│ ├── goal.ogg
│ ├── jump.wav
│ ├── puff.wav
│ ├── return.wav
│ ├── ringcount.wav
│ ├── ringless.wav
│ ├── ring.wav
│ ├── scratch.wav
│ ├── select.wav
│ ├── shield.wav
│ ├── shot.wav
│ ├── spikes_appearing.wav
│ ├── spikes_disappearing.wav
│ ├── spikes.wav
│ ├── spindash1.wav
│ ├── spindash2.wav
│ ├── spin.wav
│ ├── spring.wav
│ ├── switch.wav
│ ├── teleporter.wav
│ ├── tfly1.wav
│ ├── tfly2.wav
│ ├── thundershield.wav
│ ├── touch2.wav
│ ├── touch.wav
│ ├── watershield.wav
│ └── windshield.wav
├── screenshots
│ └── screenshots.txt
├── snap
│ └── snapcraft.yaml
├── sprites
│ ├── animal.spr
│ ├── bigring.spr
│ ├── bluering.spr
│ ├── bosses.spr
│ ├── bumper.spr
│ ├── charge.spr
│ ├── checkpointorb.spr
│ ├── chef.spr
│ ├── danger.spr
│ ├── dangpower.spr
│ ├── dnadoor.spr
│ ├── door.spr
│ ├── explosion.spr
│ ├── fireball.spr
│ ├── flyingboy.spr
│ ├── flyingeyes.spr
│ ├── font.spr
│ ├── glasses.spr
│ ├── goal.spr
│ ├── goldfish.spr
│ ├── hud.spr
│ ├── icon.spr
│ ├── itembox.spr
│ ├── joan.spr
│ ├── kleps.spr
│ ├── lady_bugsy.spr
│ ├── levelact.spr
│ ├── loop.spr
│ ├── menu.spr
│ ├── misc.spr
│ ├── nafder.spr
│ ├── neon.spr
│ ├── oranjection.spr
│ ├── ring.spr
│ ├── roboxer.spr
│ ├── shield.spr
│ ├── spikes.spr
│ ├── spring.spr
│ ├── surge.spr
│ ├── surpreyes.spr
│ ├── switch.spr
│ └── teleporter.spr
└── themes
├── credits.bg
├── desert1.bg
├── desert1.brk
├── intro.bg
├── island2.bg
├── island2.brk
├── island3.bg
├── island3.brk
├── island.bg
├── island.brk
├── island.grp
├── langselect.bg
├── levelselect.bg
├── menu.bg
├── ocean2b.bg
├── ocean2.bg
├── ocean2.brk
├── oceanb.bg
├── ocean.bg
├── ocean.brk
├── oceanf.bg
├── options.bg
├── prototype.bg
├── prototype.brk
├── template.bg
├── template.brk
├── template.grp
└── tutorial.bg

13 directories, 234 files

Welcome to the community, @ixubuntu. I think snaps are great to preserve old software.

I think this snap will be very similar to what you want. This is also a 32-bit desktop app: https://github.com/snapcrafters/s4a/blob/master/snapcraft.yaml

Snaps run in a sandbox, they do not have access to the host system. This has the advantage for 32-bit apps that the i386 architecture does not have to be enabled on the computer of the user. The only thing you need to do is add all the i386 libraries that your app needs to the snap at build time.

In this example

  • the i386 part enables the architecture in the snap
  • the s4a part installs the deb (inside of the snap) and includes all the 32-bit dependencies of the application (using stage-packages).
parts:
  i386:
    plugin: nil
    override-build: |
      sudo dpkg --add-architecture i386
      sudo apt-get update  
  s4a:
    after: 
      - i386
      - glib-only
    plugin: dump
    source: http://s4a.cat/downloads/S4A16.deb
    source-type: deb
    stage-packages:
      - libsm6:i386
      - libatk1.0-0:i386
      - libbsd0:i386
      - libc6:i386
      - libcairo2:i386
      - libgcc1:i386
      - libgdk-pixbuf2.0-0:i386
      - libglib2.0-0:i386
      - libglu1-mesa:i386
      - libgtk2.0-0:i386
      - libpango-1.0-0:i386
      - libpulse0:i386
      - libx11-6:i386
      - libxau6:i386
      - libxcb1:i386
      - libxdmcp6:i386
      - libxml2:i386
      - libxrandr2:i386
      - libv4l-0:i386
    override-build: |
      snapcraftctl build
      sed -i 's|Icon=s4a|Icon=${SNAP}/usr/share/icons/hicolor/128x128/apps/s4a.png|' ${SNAPCRAFT_PART_INSTALL}/usr/share/applications/s4a.desktop
      echo "Keywords=Arduino" >> ${SNAPCRAFT_PART_INSTALL}/usr/share/applications/s4a.desktop
      rm -rf $SNAPCRAFT_PART_INSTALL/lib/x86_64-linux-gnu
      rm -rf $SNAPCRAFT_PART_INSTALL/usr/lib/x86_64-linux-gnu
      rm -rf $SNAPCRAFT_PART_INSTALL/usr/share/bug
      rm -rf $SNAPCRAFT_PART_INSTALL/usr/share/doc
      rm -rf $SNAPCRAFT_PART_INSTALL/usr/share/doc-base
      rm -rf $SNAPCRAFT_PART_INSTALL/usr/share/lintian
      rm -rf $SNAPCRAFT_PART_INSTALL/usr/share/man
    stage:
      - -usr/bin/update-mime-database

So for your snap, you will probably need to add all the dependencies of your application in stage-packages of your opensonic part. The installation instructions for opensonic will probably tell you what its dependencies are.

You will also need the glib-only part in order to enable desktop features

  glib-only:
    after: [i386]
    source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
    source-subdir: glib-only
    plugin: make
    build-packages:
      - libglib2.0-dev
    stage-packages:
      - libglib2.0-bin:i386
      - shared-mime-info:i386

I think you’ll also need the launcher part (also copy the script folder into your snap) and add bin/launcher and bin/desktop-launch to the command chain, so all the desktop stuff gets initialized correctly.

1 Like

Thank you very much. Excelent reply. I have marked it as solution. Thank you for your expnations and pointing me to the right direction.

1 Like