#!/usr/bin/env bash set -euo pipefail # run from root build directory in clang64 shell (NOT mingw64) as in # ``` # eval cmake ../.. $(../../script/prepare-llvm-mingw.sh ~/Downloads/lean-llvm-x86_64-w64-windows-gnu.tar.zst) # ``` # use full LLVM release for compiling C++ code, but subset for compiling C code and distribution # must run `tar` twice in case of symlinked files listed before their targets... [[ -d llvm ]] || (mkdir llvm; tar xf $1 --dereference --strip-components 1 --directory llvm || tar xf $1 --dereference --strip-components 1 --directory llvm) mkdir -p stage1/{bin,lib,include/clang} # a C compiler! cp llvm/bin/clang stage1/bin/ # a linker! cp llvm/bin/{ld.lld,lld} stage1/bin/ # a static archiver! cp llvm/bin/llvm-ar stage1/bin/ # dependencies of the above cp $(ldd llvm/bin/{clang,lld,llvm-ar}.exe | cut -f3 -d' ' --only-delimited | grep -E 'llvm|clang64') stage1/bin # lean.h dependencies cp llvm/lib/clang/*/include/{std*,__std*,limits}.h stage1/include/clang # single Windows dependency echo ' // https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-seterrormode #define SEM_FAILCRITICALERRORS 0x0001 __declspec(dllimport) __stdcall unsigned int SetErrorMode(unsigned int uMode); // https://docs.microsoft.com/en-us/windows/console/setconsoleoutputcp #define CP_UTF8 65001 __declspec(dllimport) __stdcall int SetConsoleOutputCP(unsigned int wCodePageID);' > stage1/include/clang/windows.h # COFF dependencies cp /clang64/lib/{crtbegin,crtend,crt2,dllcrt2}.o stage1/lib/ # runtime (cd llvm; cp --parents lib/clang/*/lib/*/libclang_rt.builtins* ../stage1) # further dependencies # Note: even though we're linking against libraries like `libbcrypt.a` which appear to be static libraries from the file name, # we're not actually linking statically against the code. # Rather, `libbcrypt.a` is an import library (see https://en.wikipedia.org/wiki/Dynamic-link_library#Import_libraries) that just # tells the compiler how to dynamically link against `bcrypt.dll` (which is located in the System32 folder). # This distinction is relevant specifically for `libicu.a`/`icu.dll` because there we want updates to the time zone database to # be delivered to users via Windows Update without having to recompile Lean or Lean programs. cp /clang64/lib/lib{m,bcrypt,mingw32,moldname,mingwex,msvcrt,pthread,advapi32,shell32,user32,kernel32,ucrtbase,psapi,iphlpapi,userenv,ws2_32,dbghelp,ole32,icu}.* /clang64/lib/libgmp.a /clang64/lib/libuv.a llvm/lib/lib{c++,c++abi,unwind}.a stage1/lib/ echo -n " -DLEAN_STANDALONE=ON" echo -n " -DCMAKE_C_COMPILER=$PWD/stage1/bin/clang.exe -DCMAKE_C_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER=$PWD/llvm/bin/clang++.exe -DCMAKE_CXX_COMPILER_WORKS=1 -DLEAN_CXX_STDLIB='-lc++ -lc++abi'" echo -n " -DSTAGE0_CMAKE_C_COMPILER=clang -DSTAGE0_CMAKE_CXX_COMPILER=clang++" echo -n " -DLEAN_EXTRA_CXX_FLAGS='--sysroot $PWD/llvm -idirafter /clang64/include/'" echo -n " -DLEANC_INTERNAL_FLAGS='--sysroot ROOT -nostdinc -isystem ROOT/include/clang' -DLEANC_CC=ROOT/bin/clang.exe" echo -n " -DLEANC_INTERNAL_LINKER_FLAGS='--sysroot ROOT -L ROOT/lib -Wl,-Bstatic -lgmp $(pkg-config --static --libs libuv) -lunwind -Wl,-Bdynamic -fuse-ld=lld'" # when not using the above flags, link GMP dynamically/as usual. Always link ICU dynamically. echo -n " -DLEAN_EXTRA_LINKER_FLAGS='-lgmp $(pkg-config --libs libuv) -lucrtbase'" # do not set `LEAN_CC` for tests echo -n " -DLEAN_TEST_VARS=''"