I'm successfully make multilib LFS with a little modifications from original LFS book. So i'm gonna share it with anyone wanna try it or its gonna be future reference. All this method i got from
https://www.williamfeely.info/lfs-multilib/ which i'm simplified it and some google around. I've been using this method few times to build my LFS based distro, so far wine and steam work great
First you gonna need make multilib toolchain (chapter 5) then make final system multilib (chapter 6). Affected package need change build command is binutils, glibc, gcc and libstdc++. At the end all 32bit libraries is placed in /usr/lib32 directory.
On chapter 5,
1) binutils pass1, on configure cmd, replace:
Code:
--with-lib-path=/tools/lib
with
Code:
--with-lib-path=/tools/lib:/tools/lib32
then make lib32 directory in /tools directory
Code:
mkdir -p /tools/lib32
2) gcc pass1, replace:
Code:
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
with
Code:
sed -i -e 's@/lib/ld-linux.so.2@/lib32/ld-linux.so.2@g' gcc/config/i386/linux64.h
sed -i -e '/MULTILIB_OSDIRNAMES/d' gcc/config/i386/t-linux64
echo "MULTILIB_OSDIRNAMES = m64=../lib m32=../lib32 mx32=../libx32" >> gcc/config/i386/t-linux64
on configure cmd, replace:
with
Code:
--with-multilib-list=m32,m64
3) glibc, you need build two times, first for 32bit lib, then 64bit. Make sure you build 32bit first.
for 32bit lib build using this cmd:
Code:
mkdir -v build32
cd build32
echo slibdir=/tools/lib32 > configparms
../configure \
--prefix=/tools \
--host=i686-lfs-linux-gnu \
--build=$(../scripts/config.guess) \
--libdir=/tools/lib32 \
--enable-kernel=3.2 \
--enable-add-ons \
--with-headers=/tools/include \
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes \
CC="$LFS_TGT-gcc -m32" \
CXX="$LFS_TGT-g++ -m32"
make
make install
for 64bit, build normally like in the book. Then you can check if you can if compiling and linking working fine
Code:
echo 'int main(){}' > dummy.c
$LFS_TGT-gcc dummy.c
readelf -l a.out | grep ': /tools'
$LFS_TGT-gcc -m32 dummy.c
readelf -l a.out | grep ': /tools'
the result should be like this for 64 and 32 bit:
Code:
[Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]
[Requesting program interpreter: /tools/lib32/ld-linux.so.2]
4) libstdc++, you need to build two times just like glibc, build 32bit (make sure change 'GCC VERSION' below):
Code:
mkdir -v build32
cd build32
../libstdc++-v3/configure \
--host=i686-lfs-linux-gnu \
--prefix=/tools \
--libdir=/tools/lib32 \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-threads \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/<GCC VERSION> \
CC="$LFS_TGT-gcc -m32" \
CXX="$LFS_TGT-g++ -m32"
make
make install
then build libstdc++ 64bit just like in the book.
5) binutils pass2, build like in the book then replace:
Code:
make -C ld LIB_PATH=/usr/lib:/lib
with
Code:
make -C ld LIB_PATH=/usr/lib:/lib:/usr/lib32:/lib32
6) gcc pass2, just like gcc pass1, replace:
Code:
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
with
Code:
sed -i -e 's@/lib/ld-linux.so.2@/lib32/ld-linux.so.2@g' gcc/config/i386/linux64.h
sed -i -e '/MULTILIB_OSDIRNAMES/d' gcc/config/i386/t-linux64
echo "MULTILIB_OSDIRNAMES = m64=../lib m32=../lib32 mx32=../libx32" >> gcc/config/i386/t-linux64
and replace:
with
Code:
--with-multilib-list=m32,m64
build the rest of chapter 5 follow the book.
7) strip section, strip debugging symbols from 32bit libraries and remove libtool (*.la) files.
Code:
strip --strip-debug /tools/lib32/*
find /tools/lib32 -name \*.la -delete
On chapter 6, for main LFS system,
1) glibc, for 64bit build, add to configure cmd:
Code:
--enable-multi-arch --enable-obsolete-rpc
then build for 32bit libraries:
Code:
mkdir -v ../build32
cd ../build32
CC="gcc -m32" \
CXX="g++ -m32" \
../configure --prefix=/usr \
--disable-werror \
--enable-kernel=3.2 \
--enable-multi-arch \
--enable-obsolete-rpc \
--enable-stack-protector=strong \
--libdir=/usr/lib32 \
--libexecdir=/usr/lib32 \
libc_cv_slibdir=/usr/lib32 \
i686-pc-linux-gnu
make
make install_root=$PWD/DESTDIR install
install -vdm755 /usr/lib32
cp -Rv DESTDIR/usr/lib32/* /usr/lib32/
install -vm644 DESTDIR/usr/include/gnu/{lib-names,stubs}-32.h \
/usr/include/gnu/
ln -sv ../usr/lib32/ld-linux.so.2 /lib/ld-linux.so.2
ln -sv ../usr/lib32/ld-linux.so.2 /lib/ld-lsb.so.3
ln -sv ../lib/locale /usr/lib32/locale
echo "/usr/lib32" > /etc/ld.so.conf.d/lib32.conf
2) binutils, add this to configure cmd:
Code:
--enable-multilib --with-lib-path=/usr/lib:/lib:/usr/lib32
3) gcc, add this to configure cmd:
4) Sanity test, its a little bit different from pure64 LFS.
for 64bit:
Quote:
+ echo 'int main(){}'
+ cc dummy.c -v -Wl,--verbose
+ readelf -l a.out
+ grep ': /lib'
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
+ grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib/crt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib/crtn.o succeeded
+ grep -B4 '^ /usr/include' dummy.log
#include <...> search starts here:
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include
/usr/local/include
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include-fixed
/usr/include
+ grep 'SEARCH.*/usr/lib' dummy.log
+ sed 's|; |\n|g'
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib");
+ grep '/lib.*/libc.so.6 ' dummy.log
attempt to open /lib/libc.so.6 succeeded
+ grep found dummy.log
found ld-linux-x86-64.so.2 at /lib/ld-linux-x86-64.so.2
|
for 32bit (add '-m32' to cc):
Quote:
+ echo 'int main(){}'
+ cc -m32 dummy.c -v -Wl,--verbose
+ readelf -l a.out
+ grep ': /lib'
[Requesting program interpreter: /lib/ld-linux.so.2]
+ grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib32/crt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib32/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib32/crtn.o succeeded
+ grep -B4 '^ /usr/include' dummy.log
#include <...> search starts here:
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include
/usr/local/include
/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include-fixed
/usr/include
+ grep 'SEARCH.*/usr/lib' dummy.log
+ sed 's|; |\n|g'
SEARCH_DIR("/usr/i386-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i386-pc-linux-gnu/lib");
+ grep '/lib.*/libc.so.6 ' dummy.log
attempt to open /usr/lib32/libc.so.6 succeeded
+ grep found dummy.log
found ld-linux.so.2 at /usr/lib32/ld-linux.so.2
|
then build the rest follow the book.
Now you should have multilib LFS
for future build of any 32bit lib should build using:
Code:
CC="gcc -m32" \
CXX="g++ -m32" \
PKG_CONFIG_PATH="/usr/lib32/pkgconfig" \
./configure --prefix=/usr \
--libdir=/usr/lib32
make
make DESTDIR=$PWD/DESTDIR install
cp -Rv DESTDIR/usr/lib32/* /usr/lib32
Extra
some package in BLFS need modification to make it work with its 32 version side by side
1) python 64bit (both v2.7 and v3.7), rename pyconfig.h to pyconfig-64.h
Code:
mv /usr/include/python2.7/pyconfig{,-64}.h
mv /usr/include/python3.7m/pyconfig{,-64}.h
then make a wrapper script called
pyconfig.h to /usr/include/python2.7/ and /usr/include/python3.7m/ directory:
Code:
/* pyconfig.h stub */
#ifndef __STUB__PYCONFIG_H__
#define __STUB__PYCONFIG_H__
#if defined(__x86_64__) || \
defined(__sparc64__) || \
defined(__arch64__) || \
defined(__powerpc64__) || \
defined(__s390x__)
#include "pyconfig-64.h"
#else
#include "pyconfig-32.h"
#endif
#endif
for 32bit python, install to tmp location then copy all its 32bit libs to /usr/lib32/ and its pyconfig.h to /usr/include/python{2.7,3.7m}/pyconfig-32.h
2) llvm 64bit, rename llvm-config.h to llvm-config-64.h
Code:
mv /usr/include/llvm/Config/llvm-config{,-64}.h
then make a wrapper script called llvm-config.h to /usr/include/llvm/Config/ directory:
Code:
#include <bits/wordsize.h>
#if __WORDSIZE == 32
#include "llvm-config-32.h"
#elif __WORDSIZE == 64
#include "llvm-config-64.h"
#else
#error "Unknown word size"
#endif
for llvm 32bit, build using this:
Code:
mv ../cfe-$version.src tools/clang
mv ../compiler-rt-$version.src projects/compiler-rt
mkdir -v build
cd build
CC="gcc -m32" \
CXX="g++ -m32" \
PKG_CONFIG_PATH="/usr/lib32/pkgconfig" \
cmake .. -G Ninja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DLLVM_ENABLE_FFI=ON \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_BUILD_LLVM_DYLIB=ON \
-DLLVM_LINK_LLVM_DYLIB=ON \
-DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DLLVM_LIBDIR_SUFFIX=32 \
-DCMAKE_C_FLAGS:STRING=-m32 \
-DCMAKE_CXX_FLAGS:STRING=-m32 \
-DLLVM_TARGET_ARCH:STRING=i686 \
-DLLVM_DEFAULT_TARGET_TRIPLE="i686-pc-linux-gnu" \
-Wno-dev
ninja
DESTDIR=$PWD/DESTDIR ninja install
cp -Rv DESTDIR/usr/lib32/* /usr/lib32/
install -m 0755 -D DESTDIR/usr/bin/llvm-config /usr/bin/llvm-config-32
install -m 0644 -D DESTDIR/usr/include/llvm/Config/llvm-config.h /usr/include/llvm/Config/llvm-config-32.h
thats all i think for now.
for more 32bit package you can check here:
https://github.com/emmett1/ports
I hope someone can make it work too using this method.
I already use this method many times but with my own script and package manager.
Anyway, if you faced any problem you can check my script to bootstrap my distro here:
https://github.com/emmett1/venom
Or you can try out my LFS based distro which is used BSD-style init and port system for packages. Get the installable iso here:
https://sourceforge.net/projects/venomlinux/
Edit: add sanity test result and strip symbols from 32bit libraries (/tools/lib32)