#!/bin/sh # ===== Overview # This script is designed to download, compile, and install Fil-C # using paths suitable for Debian (and various other distributions), # viewing Fil-C as a cross-compiler for purposes of Debian packaging. # The main installation is in /usr/libexec/fil/x86_64 (about 13GB). # The compilation directory (>50GB) can be removed afterwards. # Symlinks installed from other directories into the main installation: # /usr/bin/{filcc,fil++} # /usr/bin/x86_64fil-linux-gnu-{gcc,g++,objdump} # /usr/lib/x86_64fil-linux-gnu # /usr/include/x86_64fil-linux-gnu # The compiler's default search paths: # /usr/include/x86_64fil-linux-gnu:/usr/include # /usr/lib/x86_64fil-linux-gnu:/usr/lib # The Fil-C compilation of glibc-2.40 # is installed in /usr/lib/x86_64fil-linux-gnu # with include files in /usr/include/x86_64fil-linux-gnu; # /usr/include would be safe if system version of glibc matched, # but not worth taking risks for a few MB of .h files. # ===== Prerequisites # Need quite a bit of disk space. 80GB is enough. # Need some compilation tools. The following should suffice (probably overkill): # apt install autoconf-dickey build-essential bison clang cmake gawk gettext ninja-build patchelf quilt ruby texinfo time # Need the compiling user (e.g., filian) to be able to run sudo: # echo 'filian ALL=(ALL) ROLE=unconfined_r TYPE=unconfined_t NOPASSWD: ALL' > /etc/sudoers.d/filian # ===== # Copyright (c) 2025 Epic Games, Inc. All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY EPIC GAMES, INC. ``AS IS AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EPIC GAMES, INC. OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # 20251029 djb: # * start from build_all_fast_glibc.sh # * merge shell scripts used, but skip overrides # * assume Linux and amd64 # * reorganize and streamline a bit # * main point: install in /usr/libexec/fil instead of ./pizfix # * create symlinks from /usr/include/x86_64fil-linux-gnu etc. # ===== set -e set -x umask 022 MAKE=make CCPREFIX="" ARCH=x86_64 LLVMARCH=X86 INCLARCH=/usr/include/${ARCH}-linux-gnu INCLARCHFIL=/usr/include/${ARCH}fil-linux-gnu LIBARCHFIL=/usr/lib/${ARCH}fil-linux-gnu BINARCHFIL=/usr/bin/${ARCH}fil-linux-gnu TOP=/usr/libexec/fil/$ARCH NCPU=`nproc` CMAKEOPTIONS="-S ../llvm -B . -G Ninja -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi -DLIBCXXABI_HAS_PTHREAD_API=ON -DLIBCXX_ENABLE_EXCEPTIONS=ON -DLIBCXXABI_ENABLE_EXCEPTIONS=ON -DLIBCXX_HAS_PTHREAD_API=ON -DLLVM_ENABLE_ZSTD=OFF -DLIBCXXABI_USE_LLVM_UNWINDER=OFF -DLIBCXX_FORCE_LIBCXXABI=ON -DLLVM_TARGETS_TO_BUILD=$LLVMARCH -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_LIBPFM=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_ZSTD=OFF -DLLVM_ENABLE_CURL=OFF -DLLVM_ENABLE_HTTPLIB=OFF -DLLVM_STATIC_LINK_CXX_STDLIB=ON -DCMAKE_EXE_LINKER_FLAGS=-static-libgcc" # ===== obtain and slightly patch repo git clone https://github.com/pizlonator/fil-c.git cd fil-c git checkout 1bc85c2bc8fee42221379ea45275674d5aa96b2a sed -i s/pizfix/top/g libpas/Makefile patch -p1 << 'EOF' diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index ee4deb44d28a..029c4a4d261f 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -593,7 +593,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); auto GetYoloLibPath = [&] (const StringRef str) -> std::string { - if (ToolChain.getDriver().HasPizfix) { + // 20251029 djb: focusing here on debian on amd64 + if ((true)) { + SmallString<128> P("/usr/lib/x86_64fil-linux-gnu"); + llvm::sys::path::append(P, str); + return std::string(P); + } else if (ToolChain.getDriver().HasPizfix) { SmallString<128> P(ToolChain.getDriver().Dir); llvm::sys::path::append(P, "..", "..", "pizfix"); llvm::sys::path::append(P, "lib", str); @@ -610,6 +615,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, }; auto GetGCCLibPath = [&] (const char* str) -> std::string { + // 20251029 djb: focusing here on debian on amd64 + return ToolChain.GetFilePath(str); if (ToolChain.getDriver().HasPizfix || ToolChain.getDriver().HasOptfil) return ToolChain.GetFilePath(str); // FIXME LMAO @@ -680,7 +687,15 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); - if (ToolChain.getDriver().HasPizfix) { + // 20251029 djb: focusing here on debian on amd64 + if ((true)) { + CmdArgs.push_back("-L/usr/lib/x86_64fil-linux-gnu"); + CmdArgs.push_back("-rpath"); + CmdArgs.push_back("/usr/lib/x86_64fil-linux-gnu"); + CmdArgs.push_back("-L/usr/lib"); + CmdArgs.push_back("-rpath"); + CmdArgs.push_back("/usr/lib"); + } else if (ToolChain.getDriver().HasPizfix) { { SmallString<128> P(ToolChain.getDriver().Dir); llvm::sys::path::append(P, "..", "..", "pizfix", "lib64"); @@ -737,7 +752,10 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_r) || Args.hasArg(options::OPT_normalcrt)) { - if (ToolChain.getDriver().HasPizfix) { + // 20251029 djb: focusing here on debian on amd64 + if ((true)) { + CmdArgs.push_back("/usr/lib/x86_64fil-linux-gnu/filc_crt.o"); + } else if (ToolChain.getDriver().HasPizfix) { SmallString<128> P(ToolChain.getDriver().Dir); llvm::sys::path::append(P, "..", "..", "pizfix", "lib"); llvm::sys::path::append(P, "filc_crt.o"); @@ -747,7 +765,10 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, else CmdArgs.push_back("/usr/lib/filc_crt.o"); } else { - if (ToolChain.getDriver().HasPizfix) { + // 20251029 djb: focusing here on debian on amd64 + if ((true)) { + CmdArgs.push_back("/usr/lib/x86_64fil-linux-gnu/filc_mincrt.o"); + } else if (ToolChain.getDriver().HasPizfix) { SmallString<128> P(ToolChain.getDriver().Dir); llvm::sys::path::append(P, "..", "..", "pizfix", "lib"); llvm::sys::path::append(P, "filc_mincrt.o"); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 6ed5145451ea..249924d5ba5e 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -456,6 +456,10 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { const llvm::Triple::ArchType Arch = getArch(); const llvm::Triple &Triple = getTriple(); + // 20251029 djb: focusing here on debian on amd64 + // XXX: figure out a broader trigger later + return "/usr/lib/x86_64fil-linux-gnu/ld-yolo-x86_64.so"; + if ((true)) { if (getDriver().HasPizfix) { SmallString<128> P(getDriver().Dir); @@ -654,7 +658,11 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, const Driver &D = getDriver(); std::string SysRoot = computeSysRoot(); - if (D.HasPizfix) { + // 20251029 djb: focusing here on debian on amd64 + if ((true)) { + addSystemInclude(DriverArgs, CC1Args, "/usr/include/x86_64fil-linux-gnu"); + addSystemInclude(DriverArgs, CC1Args, "/usr/include"); + } else if (D.HasPizfix) { { SmallString<128> P(D.Dir); llvm::sys::path::append(P, "..", "..", "pizfix", "stdfil-include"); EOF # ===== initialize target directories sudo sh -c " set -e set -x rm -rf $TOP mkdir -p $TOP /usr/include /usr/lib rm -rf $INCLARCHFIL ln -s $TOP/include $INCLARCHFIL rm -rf $LIBARCHFIL ln -s $TOP/lib $LIBARCHFIL chown $USER $TOP # will revert later " rm -rf top ln -s $TOP top # ===== maybe clean up build directory EXPECTEDCOOKIECONTENTS="$HOSTNAME:$PWD ::: $CMAKEOPTIONS" COOKIENAME=filc_cookie_2.txt if test -e build/$COOKIENAME then ACTUALCOOKIECONTENTS=`cat build/$COOKIENAME` else ACTUALCOOKIECONTENTS="" fi if test "x$ACTUALCOOKIECONTENTS" != "x$EXPECTEDCOOKIECONTENTS" then rm -rf build mkdir -p build ( cd build cmake $CMAKEOPTIONS echo "$EXPECTEDCOOKIECONTENTS" > $COOKIENAME ) fi # ===== build/bin/clang-20 and friends ( cd build && ninja clang ) patchelf --remove-rpath build/bin/clang-20 # ===== $TOP/include/* from filc/include/* # ===== $TOP/include/asm as symlink to $INCLARCH/asm rm -rf $TOP/include mkdir -p $TOP/include cp filc/include/* $TOP/include/ ln -s $INCLARCH/asm $TOP/include/asm # ===== $TOP/yolo-include # ===== $TOP/lib ( cd projects/yolo-glibc-2.40 rm -f configure autoconf ) ( rm -rf pizlonated-yolo-glibc-build mkdir pizlonated-yolo-glibc-build cd pizlonated-yolo-glibc-build ../projects/yolo-glibc-2.40/configure --prefix=$TOP/yolo --disable-mathvec make -j $NCPU make -j $NCPU install ) ( cd $TOP OLDLDNAME=ld-linux-x86-64.so.2 OLDLIBCIMPLNAME=libc.so.6 OLDLIBCNONSHAREDNAME=libc_nonshared.a OLDLIBMIMPLNAME=libm.so.6 OLDSTATICLIBCNAME=libc.a OLDSTATICLIBMNAME=libm.a LDNAME=ld-yolo-x86_64.so LIBNAMEBASE=libyolo LIBCNAMEBASE=${LIBNAMEBASE}c LIBCNAME=${LIBCNAMEBASE}.so LIBCIMPLNAME=${LIBCNAMEBASE}impl.so LIBCNONSHAREDNAME=${LIBCNAMEBASE}_nonshared.a LIBMIMPLNAME=${LIBNAMEBASE}mimpl.so LIBMNAME=${LIBNAMEBASE}m.so STATICLIBCNAME=${LIBCNAMEBASE}.a STATICLIBMNAME=${LIBNAMEBASE}m.a mkdir -p lib cp yolo/lib/$OLDLDNAME lib/$LDNAME cp yolo/lib/$OLDLIBCIMPLNAME lib/$LIBCIMPLNAME cp yolo/lib/$OLDLIBCNONSHAREDNAME lib/$LIBCNONSHAREDNAME cp yolo/lib/$OLDLIBMIMPLNAME lib/$LIBMIMPLNAME cp yolo/lib/*.o lib/ cp yolo/lib/$OLDSTATICLIBCNAME lib/$STATICLIBCNAME cp yolo/lib/$OLDSTATICLIBMNAME lib/$STATICLIBMNAME patchelf --replace-needed $OLDLDNAME $LDNAME lib/$LIBCIMPLNAME patchelf --set-soname $LIBCIMPLNAME lib/$LIBCIMPLNAME patchelf --set-soname $LDNAME lib/$LDNAME patchelf --replace-needed $OLDLDNAME $LDNAME lib/$LIBMIMPLNAME patchelf --replace-needed $OLDLIBCIMPLNAME $LIBCIMPLNAME lib/$LIBMIMPLNAME patchelf --set-soname $LIBMIMPLNAME lib/$LIBMIMPLNAME echo "OUTPUT_FORMAT(elf64-x86-64)" > lib/$LIBCNAME echo "GROUP ( $PWD/lib/$LIBCIMPLNAME $PWD/lib/$LIBCNONSHAREDNAME AS_NEEDED ( $PWD/lib/$LDNAME ) )" >> lib/$LIBCNAME echo "OUTPUT_FORMAT(elf64-x86-64)" > lib/$LIBMNAME echo "GROUP ( $PWD/lib/$LIBMIMPLNAME )" >> lib/$LIBMNAME rm -rf yolo-include mv yolo/include yolo-include rm -rf yolo ln -s . yolo # XXX: there are still refs to yolo # help libpas because it compiles with nostdinc: ln -s $INCLARCH/asm yolo-include/ ln -s /usr/include/asm-generic yolo-include/ ln -s /usr/include/linux yolo-include/ ) # ===== $TOP/lib/{filc_crt.o,filc_mincrt.o,libpizlo.a,libpizlo.so} # ===== $TOP/lib_gcverify/libpizlo.so # ===== $TOP/lib_test/libpizlo.so # ===== $TOP/lib_test_gcverify/libpizlo.so # ===== plus some $TOP/* empty directories ( cd libpas $MAKE -f Makefile clean # XXX: most of these logically belong elsewhere mkdir -p build mkdir -p $TOP/include mkdir -p $TOP/bin mkdir -p $TOP/sbin mkdir -p $TOP/libexec mkdir -p $TOP/share mkdir -p $TOP/lib mkdir -p $TOP/lib_gcverify mkdir -p $TOP/lib_test mkdir -p $TOP/lib_test_gcverify mkdir -p $TOP/man mkdir -p $TOP/man/man1 $MAKE -f Makefile -j $NCPU ) # ===== $TOP/bin/* for glibc # ===== $TOP/etc/* for glibc # ===== $TOP/libexec/* for glibc # ===== $TOP/sbin/* for glibc # ===== $TOP/share/* for glibc # ===== $TOP/var/* for glibc # ===== $TOP/include/* extended for glibc # ===== $TOP/lib/* extended for glibc ( cd projects/user-glibc-2.40 rm -f configure autoconf ) ( rm -rf pizlonated-user-glibc-build mkdir pizlonated-user-glibc-build cd pizlonated-user-glibc-build CC="$PWD/../build/bin/clang -nostdlibinc -Wno-ignored-attributes -Wno-pointer-sign -Wno-unused-command-line-argument -Wno-macro-redefined" CXX="$PWD/../build/bin/clang++ -nostdlibinc -Wno-ignored-attributes -Wno-pointer-sign" ../projects/user-glibc-2.40/configure --prefix=$TOP --disable-mathvec make -j $NCPU make -j $NCPU install ) # ===== $TOP/include/crypt.h # ===== $TOP/include/xcrypt.h # ===== $TOP/lib/lib*crypt* # ===== $TOP/lib/pkgconfig # ===== $TOP/share/man ( cd projects/libxcrypt-4.4.36 rm -rf extracted-source git archive --format=tar HEAD --prefix=extracted-source/ | tar -xf - git diff --relative HEAD . | (cd extracted-source && patch -p1) cd extracted-source CC=$PWD/../../../build/bin/clang ./configure --prefix=$TOP make -j $NCPU make -j $NCPU install ) # ===== $TOP/lib/libc++* ( cd build ninja runtimes-clean ninja runtimes ) cp build/lib/x86_64-unknown-linux-gnu/libc++.so $TOP/lib cp build/lib/x86_64-unknown-linux-gnu/libc++.so.1.0 $TOP/lib cp build/lib/x86_64-unknown-linux-gnu/libc++abi.so.1.0 $TOP/lib cp build/lib/x86_64-unknown-linux-gnu/libc++.a $TOP/lib cp build/lib/x86_64-unknown-linux-gnu/libc++abi.a $TOP/lib ( cd $TOP/lib && ln -fs libc++.so.1.0 libc++.so.1 && ln -fs libc++abi.so.1.0 libc++abi.so.1 && ln -fs libc++abi.so.1 libc++abi.so ) patchelf --remove-rpath build/bin/clang-20 # ===== extend $TOP/bin/* for compiler mkdir -p $TOP/bin ls build/bin | while read fn do case $fn in clang|clang++|clang-cl|clang-cpp|fil++|filcc|filcpp|g++|gcc|llvm-ranlib|llvm-readelf|llvm-strip) ;; *) cp build/bin/$fn $TOP/bin/ esac done ( cd $TOP/bin ln -fs clang-20 filcc ln -fs clang-20 fil++ ln -fs clang-20 filcpp ln -fs clang-20 gcc ln -fs clang-20 g++ ln -fs clang-20 clang ln -fs clang-20 clang++ ln -fs clang-20 clang-cl ln -fs clang-20 clang-cpp ln -fs llvm-ar llvm-ranlib ln -fs llvm-readobj llvm-readelf ln -fs llvm-objcopy llvm-strip ) rm -rf $TOP/build ln -s . $TOP/build # to help filc/run-tests # ===== extend $TOP/include/* for compiler cp -r build/include/c++ $TOP/include/ cp -r build/include/${ARCH}* $TOP/include/ # ===== extend $TOP/lib/* for compiler cp -r build/lib/clang $TOP/lib/ # ===== install ${BINARCHFIL}-{filcc,fil++,gcc,g++,objdump} # and have root own everything sudo sh -c " ln -fs $TOP/bin/filcc /usr/bin/filcc ln -fs $TOP/bin/fil++ /usr/bin/fil++ ln -fs $TOP/bin/gcc ${BINARCHFIL}-gcc ln -fs $TOP/bin/g++ ${BINARCHFIL}-g++ ln -fs $TOP/bin/llvm-objdump ${BINARCHFIL}-objdump chown -R root:root $TOP " # ===== tests filc/run-tests -p $TOP/bin