cleanup mips32r2.py and use python class inheritance for flavors

added
  mips32r2_uclibc_gclibcxx_dyn,  (preferred atm, tested on prod hw)
  mips32r2_uclibc_gclibcxx_static
targets (shared) and renamed previous uclibc ones to
  mips32r2_uclibc_uclibcxx_dyn,
  mips32r2_uclibc_uclibcxx_static
for clarity (i.e. non-shared, pure ones)

reworked builder classes to use inheritance of properties and
methods (instead of copying boiler plate code)

mips32r2_uclibc_gclibcxx_dyn target compiles and tested to run on
production targets such as avm routers modified with a freetz env.

See cm8/freetz@41d97c3789 for one of
many possible projects to build a working toolchain with.  In short
- git clone
- umask 0022
- make menuconfig (choose expert, disable toolchain download and
let the toolchain/make scripts built a gcc-5.x one, do not forget
to set FREETZ_LIB_libuClibc__WITH_WCHAR=y)
- read the commit message for further info on long double math
peculiarities
- tested here with 0.9.33.2

Remember that swap will need to be running on the box, or else
kiwix-serve is likely to quit with "invalid lzma stream in cluster"
errors (if memory is too low).

If the box lacks library support such as libstdc++.so*, you can
copy them from the target toolchain libdir over to
BUILD_mips32r2_uclibc_gclibcxx_dyn/INSTALL/lib if there are
unsatisfied dependencies at runtime.  (Which libraries need to be
supplemented this way depends on your firmware and/or freetz
configuration).

Another issue is the execution in non-standard installation
directories.  LD_LIBRARY_PATH env needs to point to "our" lib
directory.  If you tar INSTALL/ dir, transport the result to
an embedded device, untar and wan't to run from there, it is
best to wrap all the elf binaries with a shell script that
correctly sets LD_LIBRARY_PATH.  This step has been automated,
but needs testing, see
kiwixbuild/patches/fixenv-run-in-nonstd-installdir.sh
for details.

This fixenv script is copied to INSTALL/bin during the
build and it should be run on the box, if kiwix-tools is to
reside in nonstd location (i.e. if files are not installed
or installable to /bin, /lib or their usr/ pendants).

Feel free to improve on automation of the necessary setup
steps to make mips port build and deployment easier.
This commit is contained in:
cm8 2018-06-23 11:18:08 +02:00
parent 2024187891
commit 4cbbf2325b
2 changed files with 106 additions and 83 deletions

View File

@ -0,0 +1,39 @@
#!/bin/sh
if ! test -f kiwix-serve
then
echo Needs to run in the same directory that hosts kiwix-serve binary.
exit 1
fi
find -type f | \
while read
do
if hexdump -C $REPLY | head -1 | grep -q ELF
then
mv -iv "$REPLY" "$REPLY.real"
ln -s run-nonroot "$REPLY"
fi
done
cat <<EOF > run-nonroot
#!/bin/sh
BASENAME=`basename $0`
SCRIPT=`realpath $0`
SCRIPTPATH=`dirname $SCRIPT`
if test x"$BASENAME" != xrun-nonroot
then
for fullarch in "" mips-linux-gnu
do for libdir in usr/lib lib
do LD_LIBRARY_PATH="${SCRIPTPATH%/bin}/$libdir/$fullarch:$LD_LIBRARY_PATH"
done
done
export LD_LIBRARY_PATH
exec ${SCRIPTPATH}/$BASENAME.real "$@"
fi
EOF
chmod +x run-nonroot

View File

@ -2,10 +2,13 @@ from .base import PlatformInfo
from kiwixbuild.utils import pj from kiwixbuild.utils import pj
from kiwixbuild._global import get_target_step from kiwixbuild._global import get_target_step
from os import makedirs, chmod
from shutil import copy
from .base import _SCRIPT_DIR
class MIPS32R2PlatformInfo(PlatformInfo): class MIPS32R2PlatformInfo(PlatformInfo):
build = 'mips32r2' build = 'mips32r2_glibc_glibcxx'
arch_full = 'mips-linux-gnu' arch_full = 'mips-linux-gnu'
compatible_hosts = ['fedora', 'debian'] compatible_hosts = ['fedora', 'debian']
@ -28,11 +31,24 @@ class MIPS32R2PlatformInfo(PlatformInfo):
@property @property
def root_path(self): def root_path(self):
# apt-get'able debian/ubuntu hard-float glibc glibcxx toolchain
return '/usr/mips-linux-gnu' return '/usr/mips-linux-gnu'
@property
def tcbindir(self):
return pj(self.root_path, 'bin')
@property
def tcbinprefix(self):
return '../../bin/' + self.arch_full + '-'
@property
def tclibdir(self):
return pj(self.root_path, 'lib')
@property @property
def binaries(self): def binaries(self):
binaries = ((k,'{}-{}'.format(self.arch_full, v)) binaries = ((k,'{}{}'.format(self.tcbinprefix, v))
for k, v in (('CC', 'gcc'), for k, v in (('CC', 'gcc'),
('CXX', 'g++'), ('CXX', 'g++'),
('AR', 'ar'), ('AR', 'ar'),
@ -41,7 +57,7 @@ class MIPS32R2PlatformInfo(PlatformInfo):
('RANLIB', 'ranlib'), ('RANLIB', 'ranlib'),
('LD', 'ld')) ('LD', 'ld'))
) )
return {k:pj('/usr', 'bin', v) return {k:pj(self.tcbindir, v)
for k,v in binaries} for k,v in binaries}
@property @property
@ -57,23 +73,14 @@ class MIPS32R2PlatformInfo(PlatformInfo):
def configure_option(self): def configure_option(self):
return '--host={}'.format(self.arch_full) return '--host={}'.format(self.arch_full)
def get_bin_dir(self):
return [pj(self.root_path, 'bin')]
def set_env(self, env): def set_env(self, env):
env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') env['PKG_CONFIG_LIBDIR'] = pj(self.tclibdir, 'pkgconfig')
# soft float is another abi and thus unsupported by current maintained (apt-get'able) debian/ubuntu tcs,
# additionally these are (gnu) libc only; if uclibc is needed, see https://buildroot.org/downloads/ and
# make a toolchain and rootfs, then checkout and use kiwixbuild --target_platform native_* within chroot env
# (it needs qemu-mips-static from host copied to rootfs/usr/bin, in order to chroot into using a non-mips-host)
#env['CFLAGS'] = " -march=mips32r2 -mtune=24kc -msoft-float "+env['CFLAGS']
#env['CXXFLAGS'] = " -march=mips32r2 -mtune=24kc -msoft-float "+env['CXXFLAGS']
env['CFLAGS'] = " -march=mips32r2 -mtune=24kc "+env['CFLAGS'] env['CFLAGS'] = " -march=mips32r2 -mtune=24kc "+env['CFLAGS']
env['CXXFLAGS'] = " -march=mips32r2 -mtune=24kc "+env['CXXFLAGS'] env['CXXFLAGS'] = " -march=mips32r2 -mtune=24kc "+env['CXXFLAGS']
env['QEMU_LD_PREFIX'] = pj(self.root_path) env['QEMU_LD_PREFIX'] = pj(self.root_path)
env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format( env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format(
':'.join([ ':'.join([
pj(self.root_path, "lib"), pj(self.tclibdir),
env['LD_LIBRARY_PATH'] env['LD_LIBRARY_PATH']
])) ]))
@ -97,88 +104,65 @@ class MIPS32R2Static(MIPS32R2PlatformInfo):
class MIPS32R2_UCLIBCPlatformInfo(PlatformInfo): class MIPS32R2_UC_GCXXPlatformInfo(MIPS32R2PlatformInfo):
build = 'mips32r2_uclibc' build = 'mips32r2_uclibc_gclibcxx' # "shared, heterogenous" (gnu c++ lib "on top of" uClibc)
arch_full = 'mips-linux-uclibc' arch_full = 'mips-linux-uclibc'
compatible_hosts = ['fedora', 'debian']
def get_cross_config(self):
return {
'binaries': self.binaries,
'exec_wrapper_def': '',
'root_path': self.root_path,
'extra_libs': [ '-lm' ],
'extra_cflags': [],
'host_machine': {
'system': 'linux',
'lsystem': 'linux',
'cpu_family': 'mips32r2',
'cpu': '24kc',
'endian': 'big',
'abi': ''
}
}
@property @property
def root_path(self): def root_path(self):
return '/dev/shm/freetz/toolchain/build/mips_gcc-5.5.0_uClibc-0.9.33.2-nptl/mips-linux-uclibc' return '/dev/shm/freetz/toolchain/build/mips_gcc-5.5.0_uClibc-0.9.33.2-nptl/mips-linux-uclibc'
@property @property
def binaries(self): def tcbinprefix(self):
binaries = ((k,'{}-{}'.format(self.arch_full, v)) return self.arch_full + '-'
for k, v in (('CC', 'gcc'),
('CXX', 'g++-uc'),
('AR', 'ar'),
('STRIP', 'strip'),
('WINDRES', 'windres'),
('RANLIB', 'ranlib'),
('LD', 'ld'))
)
return {k:pj(self.root_path, 'usr', 'bin', v)
for k,v in binaries}
@property
def exec_wrapper_def(self):
try:
which('qemu-mips-static')
except subprocess.CalledProcessError:
return ""
else:
return "exec_wrapper = 'qemu-mips-static'"
@property
def configure_option(self):
return '--host={}'.format(self.arch_full)
def get_bin_dir(self):
return [pj(self.root_path, 'bin')]
def set_env(self, env): def set_env(self, env):
# altering PATH for mips-linux-uclibc-g++-uc wrapper to find real binary super().set_env(env)
env['PATH'] = ':'.join([pj(self.root_path, 'usr', 'bin'), env['PATH']]) env['CFLAGS'] = " -msoft-float -Os -pipe -Wa,--trap "+env['CFLAGS']
env['PKG_CONFIG_LIBDIR'] = pj(self.root_path, 'lib', 'pkgconfig') env['CXXFLAGS'] = " -msoft-float -Os -pipe -Wa,--trap "+env['CXXFLAGS']
env['CFLAGS'] = " -march=mips32r2 -mtune=24kc -msoft-float -Os -pipe -Wa,--trap "+env['CFLAGS']
env['CXXFLAGS'] = " -march=mips32r2 -mtune=24kc -msoft-float -Os -pipe -Wa,--trap "+env['CXXFLAGS']
env['QEMU_LD_PREFIX'] = pj(self.root_path)
env['QEMU_SET_ENV'] = "LD_LIBRARY_PATH={}".format(
':'.join([
pj(self.root_path, "lib"),
env['LD_LIBRARY_PATH']
]))
def set_compiler(self, env): class MIPS32R2_UC_GCXXDyn(MIPS32R2_UC_GCXXPlatformInfo):
env['CC'] = self.binaries['CC'] name = 'mips32r2_uclibc_gclibcxx_dyn'
env['CXX'] = self.binaries['CXX'] static = False
def finalize_setup(self): def finalize_setup(self):
super().finalize_setup() super().finalize_setup()
self.buildEnv.cmake_crossfile = self._gen_crossfile('cmake_cross_file.txt') dest = pj(_SCRIPT_DIR, '..', '..', 'BUILD_'+self.name, 'INSTALL', 'bin')
self.buildEnv.meson_crossfile = self._gen_crossfile('meson_cross_file.txt') makedirs(dest, mode=0o755, exist_ok=True)
dest = pj(dest, 'fixenv-run-in-nonstd-installdir.sh')
copy(pj(_SCRIPT_DIR, '..', 'patches', 'fixenv-run-in-nonstd-installdir.sh'), dest)
chmod(dest, 0o755)
class MIPS32R2_UCLIBCDyn(MIPS32R2_UCLIBCPlatformInfo): class MIPS32R2_UC_GCXXStatic(MIPS32R2_UC_GCXXPlatformInfo):
name = 'mips32r2_uclibc_dyn' name = 'mips32r2_uclibc_gclibcxx_static'
static = True
class MIPS32R2_UC_UCXXPlatformInfo(MIPS32R2_UC_GCXXPlatformInfo):
build = 'mips32r2_uclibc_uclibcxx' # "pure, homogenous"
def get_cross_config(self):
conf = super().get_cross_config()
conf['extra_libs'] += [ '-lm' ]
return conf
@property
def binaries(self):
bins = super().binaries
bins['CXX'] += '-uc'
return bins
def set_env(self, env):
super().set_env(env)
# for mips-linux-uclibc-g++-uc wrapper to find real binary
env['PATH'] = ':'.join([pj(self.tcbindir), env['PATH']])
class MIPS32R2_UC_UCXXDyn(MIPS32R2_UC_UCXXPlatformInfo):
name = 'mips32r2_uclibc_uclibcxx_dyn'
static = False static = False
class MIPS32R2_UCLIBCStatic(MIPS32R2_UCLIBCPlatformInfo): class MIPS32R2_UC_UCXXStatic(MIPS32R2_UC_UCXXPlatformInfo):
name = 'mips32r2_uclibc_static' name = 'mips32r2_uclibc_uclibcxx_static'
static = True static = True