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:
parent
2024187891
commit
4cbbf2325b
|
@ -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
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue