Fails to cross-compile kernel for i386

Bug #1563363 reported by Jian Luo
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Snapcraft
Fix Released
High
Paolo Pisati

Bug Description

Snapcraft fails to cross-compile kernel app for i386 since "cross-build-packages" and "cross-compiler-prefix" are not defined in common.py:

root@c134331fc9ea:/devel/luo1lo/Workspace/snappy/linux# uname -a
Linux c134331fc9ea 3.13.0-83-generic #127-Ubuntu SMP Fri Mar 11 00:25:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

root@c134331fc9ea:/devel/luo1lo/Workspace/snappy/linux# snapcraft -v
2.6

root@c134331fc9ea:/devel/luo1lo/Workspace/snappy/linux# snapcraft --target-arch i386 --debug
Setting target machine to 'i686'
Setting 'i686' as the compilation target for 'tar-content'
Setting 'i686' as the compilation target for 'kernel'
Cross compiling kernel target 'x86'
Traceback (most recent call last):
  File "/usr/bin/snapcraft", line 31, in <module>
    snapcraft.main.main()
  File "/usr/lib/python3/dist-packages/snapcraft/main.py", line 126, in main
    commands.load(cmd).main(argv=args['ARGS'])
  File "/usr/lib/python3/dist-packages/snapcraft/commands/snap.py", line 79, in main
    snap = lifecycle.execute('strip')
  File "/usr/lib/python3/dist-packages/snapcraft/lifecycle.py", line 50, in execute
    config = snapcraft.yaml.load_config()
  File "/usr/lib/python3/dist-packages/snapcraft/yaml.py", line 474, in load_config
    return Config()
  File "/usr/lib/python3/dist-packages/snapcraft/yaml.py", line 151, in __init__
    self.load_plugin(part_name, plugin_name, properties)
  File "/usr/lib/python3/dist-packages/snapcraft/yaml.py", line 258, in load_plugin
    part_name, plugin_name, properties)
  File "/usr/lib/python3/dist-packages/snapcraft/pluginhandler.py", line 580, in load_plugin
    return PluginHandler(plugin_name, part_name, properties)
  File "/usr/lib/python3/dist-packages/snapcraft/pluginhandler.py", line 136, in __init__
    self._load_code(plugin_name, properties)
  File "/usr/lib/python3/dist-packages/snapcraft/pluginhandler.py", line 168, in _load_code
    self.code.set_target_machine(common.target_machine)
  File "/usr/lib/python3/dist-packages/snapcraft/plugins/kernel.py", line 151, in set_target_machine
    self.build_packages.extend(self._target_arch['cross-build-packages'])
KeyError: 'cross-build-packages'

Workaround see attached patch.

Revision history for this message
Jian Luo (luojian) wrote :
Changed in snapcraft:
status: New → Triaged
Revision history for this message
Leo Arias (elopio) wrote :

I can reproduce this by running it on the 96boards demo:

snapcraft/demos/96boards-kernel$ snapcraft --target-arch i386 --debug

Setting priority to high, because we should never crash this way.

Changed in snapcraft:
importance: Undecided → High
tags: added: cross-compile plugin
Cris Dywan (kalikiana)
Changed in snapcraft:
assignee: nobody → Christian Dywan (kalikiana)
Revision history for this message
Cris Dywan (kalikiana) wrote :

So I looked a bit into this. The above patch isn't going to be enough. Snapcraft needs to setup the environment rather than leave it to the user - we can't assume that the system was prepared for cross-compilation.
Jian Luo, what else did you do to compile the kernel? Maybe we can compare notes here.

From a little bit of investigation:
- There's "setarch i386" to fake a native 32bit host (uts_machine in Snapcraft's context).
- gcc requires -m32 to change its output format and works perfectly with a stand-alone .c file
- From a proof of concept, ldd needs more convincing in a kbuild context. An error message tells me I need "-m elf-i386" to make things work, but it still won't link, claiming the format is wrong.
- I had to get libc6-dev-i386 - this could be added to cross-build-packages. Not sure if I may be missing something else, right now x86 is incomplete in that regard and probably not really tested.

Paolo Pisati (p-pisati)
Changed in snapcraft:
assignee: Christian Dywan (kalikiana) → Paolo Pisati (p-pisati)
Revision history for this message
Paolo Pisati (p-pisati) wrote :

A couple of things:

1) there's no x86 cross-toolchain - in other words, unless you convince Foundation to generate a cross-toolchain targeting x86, to produce an i386 kernel you would need an x86 machine (either 32 or 64 bit, that doesn't matter)

2) it's failry easy to generate an i386 kernel on a x86 host:

a) grab the latest snapcraft source and apply this patch:

diff --git a/snapcraft/_options.py b/snapcraft/_options.py
index b25bafc..d5fcd04 100644
--- a/snapcraft/_options.py
+++ b/snapcraft/_options.py
@@ -53,6 +53,7 @@ _ARCH_TRANSLATIONS = {
         'kernel': 'x86',
         'deb': 'i386',
         'uts_machine': 'i686',
+ 'cross-compiler-prefix': '',
         'triplet': 'i386-linux-gnu',
     },
     'ppc64le': {

b) generate a snapcraft.yaml like this:

$ cat << EOF > snapcraft.yaml
name: kernel
version: 4.13.5+
summary: Linux kernel
description: The upstream Linux kernel
grade: stable
confinement: strict
type: kernel

parts:
  kernel:
    plugin: kernel
    source: .
    source-type: git
    kdefconfig: [ i386_defconfig ]
EOF

c) invoke snapcraft and let it bake:

$ ~/canonical/snapcraft/bin/snapcraft --target-arch=i386
...
Staging kernel
Priming kernel
Snapping 'kernel' |
Snapped kernel_4.13.5+_i386.snap

That being said, and since we cannot target x86 on any other arch but x86 itself, i think the scope of this bug is pretty narrow - i can push the above patch to cross-compile for i386, but for all the other arches we should just catch the condition and error out gently instead of dumping out a stack trace.

Changed in snapcraft:
status: Triaged → In Progress
Revision history for this message
Paolo Pisati (p-pisati) wrote :

Better solution: it handles the cross x86_64 -> i386, and gently fails in all the other cases.

Revision history for this message
Cris Dywan (kalikiana) wrote :
Changed in snapcraft:
milestone: none → 2.35
status: In Progress → Fix Committed
Changed in snapcraft:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.