Solved Build i386 kernel and world on amd64

I am successfully running amd64 buildworld and buildkernel on a faster machine and installing to other amd64 machines. I mount nfs mount /usr/obj and /usr/src-stable-13, and then install.

I would like to do the same for i386 clients
fastmachine: amd64 13.0-STABLE FreeBSD 13.0-STABLE #0 stable/13-n246841-60833696c2e
i386 machine: i386 13.0-STABLE FreeBSD 13.0-STABLE #0 stable/13-n246841-60833696c2e

On the fast machine:
Code:
# make -j8 TARGET=i386 TARGET_ARCH=i386  buildkernel
# make -j8 TARGET=i386 TARGET_ARCH=i386   buildworld

Then on the i386 machine:
Code:
# mount -o nfsv4,soft,intr,tcp fastmachine:/usr/obj /usr/obj
# mount -o nfsv4,soft,intr,tcp fastmachine:/usr/src-stable-13 /usr/src-stable-13
# cd /usr/src-stable-13/
# make  TARGET=i386 TARGET_ARCH=i386 installkernel
--------------------------------------------------------------
>>> Install check kernel
--------------------------------------------------------------
--------------------------------------------------------------
>>> Installing kernel GENERIC on Fri Sep 17 17:46:10 EEST 2021
--------------------------------------------------------------
cd /usr/obj/usr/src-stable-13/i386.i386/sys/GENERIC;  MACHINE_ARCH=i386  MACHINE=i386  CPUTYPE= CC="cc -target i386-unknown-freebsd13.0 --sysroot=/usr/obj/usr/src-stable-13/i386.i386/tmp -B/usr/obj/usr/src-stable-13/i386.i386/tmp/usr/bin" CXX="c++  -target i386-unknown-freebsd13.0 --sysroot=/usr/obj/usr/src-stable-13/i386.i386/tmp -B/usr/obj/usr/src-stable-13/i386.i386/tmp/usr/bin"  CPP="cpp -target i386-unknown-freebsd13.0 --sysroot=/usr/obj/usr/src-stable-13/i386.i386/tmp -B/usr/obj/usr/src-stable-13/i386.i386/tmp/usr/bin"  AS="as" AR="ar" LD="ld" LLVM_LINK=""  NM=nm OBJCOPY="objcopy"  RANLIB=ranlib STRINGS=  SIZE="size" STRIPBIN="strip" PATH=/usr/obj/usr/src-stable-13/i386.i386/tmp/bin:/usr/obj/usr/src-stable-13/i386.i386/tmp/usr/sbin:/usr/obj/usr/src-stable-13/i386.i386/tmp/usr/bin:/usr/obj/usr/src-stable-13/i386.i386/tmp/legacy/usr/sbin:/usr/obj/usr/src-stable-13/i386.i386/tmp/legacy/usr/bin:/usr/obj/usr/src-stable-13/i386.i386/tmp/legacy/bin:/usr/obj/usr/src-stable-13/i386.i386/tmp/legacy/usr/libexec::/sbin:/bin:/usr/sbin:/usr/bin  make  KERNEL=kernel install
/bin/sh: make: Exec format error
*** Error code 126

Stop.
make[1]: stopped in /usr/src-stable-13
*** Error code 1

Stop.
make: stopped in /usr/src-stable-13
root@sky60:/usr/src-stable-13 # file /bin/sh
/bin/sh: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 13.0 (1300514), FreeBSD-style, stripped

What am I missing to cross compile and install correctly?
 
What am I missing to cross compile and install correctly?
The problem is that the build needs some "supportive tools" (like e.g. make(1)) that are also built from the source tree before the system itself is built. As they need to be executed during building, for a cross build, they are always built targeting the building machine's architecture (amd64 in your case).

I'm solving this by having an i386 jail on my builder and building inside this jail instead.

An alternative would be to do the install on the building machine as well, using DESTDIR to specify the root path where to install. But I never tried doing this via NFS. It probably wouldn't work because NFS doesn't support flags (chflags(1) is used during install).
 
Great, you pointed me in the right direction!

I pulled the slow machine hard drive and connected it to the fast machine.
I mounted the necessary filesytems on the slow machine to the fast machine:
The slow machine has this layout:
Code:
# cat /etc/fstab
/dev/ada0s3g    none    swap    sw    0    0
/dev/ada0s3a    /    ufs    rw    2    2
/dev/ada0s3b    /usr    ufs    rw    2    2
/dev/ada0s3d    /usr/ports    ufs    rw    2    2
/dev/ada0s3e    /var    ufs    rw    2    2
/dev/ada0s3f    /tmp    ufs    rw    2    2

I used dmesg to determine the device name of the slow hard drive.
Then mounted the filesystems:
Code:
mount /dev/ada1s3a /mnt/t60
mount /dev/ada1s3b /mnt/t60/usr
mount /dev/ada1s3e /mnt/t60/var

Now I am able to build and install on the builder machine:
Code:
cd /usr/src-stable-13
make -j8 TARGET=i386 TARGET_ARCH=i386   buildworld 
make -j8 TARGET=i386 TARGET_ARCH=i386   buildkernel
make TARGET=i386 TARGET_ARCH=i386 DESTDIR=/mnt/t60  installworld 
make TARGET=i386 TARGET_ARCH=i386 DESTDIR=/mnt/t60  installkernel

Run etcupdate:
Code:
etcupdate -s /usr/src-stable-13 -D /mnt/t60  -p
etcupdate -s /usr/src-stable-13 -D /mnt/t60
  D /etc/apmd.conf
  D /etc/rc.d/apmd
  U /boot/device.hints
  U /etc/freebsd-update.conf
  U /etc/mtree/BSD.tests.dist
  U /etc/rc.d/jail
  A /etc/mtree/BSD.lib32.dist
Warnings:
  Needs update: /etc/localtime (required manual update via tzsetup(8))


Then delete-old and delete-old-libs:
Code:
yes | make delete-old DESTDIR=/mnt/t60
yes | make delete-old-libs DESTDIR=/mnt/t60

Shutdown builder system and place hard drive back in slow machine.
 
Well, I didn't expect someone to be willing to unmount (I mean, physically) a harddrive, but sure, it works fine that way as well ;) – I prefer the approach of building inside an i386 jail and sharing the result with NFS.

A little hint: you don't need to specify TARGET_ARCH for i386, cause there is only one available anyways.
 
Back
Top