Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Rev 30 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. @echo off
  2. setlocal enableextensions enabledelayedexpansion
  3.  
  4. rem // what we're building
  5. set PRODUCT_NAME=the LLVM compiler suite
  6.  
  7. rem // the WSL distribution to use and hostname where its packages are downloaded from
  8. set WSL_DISTR=Ubuntu-22.04
  9. set WSL_SOURCE=archive.ubuntu.com
  10.  
  11. rem // name of the QNX SDK root directory
  12. set QNXSDK_DIRNAME=qnx800
  13.  
  14. rem // list of Linux tools required by the cross-build script
  15. set REQUIRED_TOOLS=wget python3 cmake gcc g++ ninja:ninja-build ccache
  16.  
  17.  
  18. rem // welcome the wary user
  19. echo QNX8 toolchain cross-build script for WSL by Pierre-Marie Baty ^<pm@pmbaty.com^>
  20. echo.
  21.  
  22. rem // make sure we have at least Windows 10
  23. for /f "tokens=4 delims=. " %%i in ('ver') do set VERSION=%%i
  24. echo Detected Windows NT kernel version: %VERSION%
  25. if %VERSION% LSS 10 (
  26.         echo.
  27.         echo Error: you need at least Windows 10 to cross-build %PRODUCT_NAME% to QNX 8.
  28.         echo Please upgrade your Windows operating system to Windows 10 version 2004 build
  29.         echo 19041 or a later version.
  30.         goto :exit_error
  31. )
  32.  
  33. rem // if WSL is not installed, do so
  34. echo|set /p=Checking whether the Windows Subsystem for Linux is installed...
  35. wsl --list -v > nul 2>&1 || ( echo no & goto :install_wsl )
  36. echo yes
  37.  
  38. rem // WSL is installed, make sure the Linux distribution we need is there
  39. echo|set /p=Checking for the presence of the GNU/Linux distribution %WSL_DISTR% in WSL...
  40. wsl --distribution %WSL_DISTR% -- cat /etc/os-release|find "%WSL_DISTR:-= %" > nul || ( echo no & goto :install_wsl )
  41. echo yes
  42.  
  43. rem // WSL is installed with the right Linux distribution, make sure it's running WSL2
  44. echo|set /p=Checking whether the WSL hypervisor is version 2...
  45. wsl --distribution %WSL_DISTR% -- cat /proc/version|find "WSL2" > nul || (
  46.         echo no
  47.         echo|set /p=Attempting to convert the WSL distribution %WSL_DISTR% to WSL2...
  48.         rem // this distribution needs to be converted
  49.         wsl --set-version %WSL_DISTR% 2 || (
  50.                 echo failed
  51.                 echo.
  52.                 echo Error: you need the Windows Subsystem for Linux to support WSL2 for this
  53.                 echo cross-build script to work consistently.
  54.                 echo Please upgrade your Windows operating system to Windows 10 version 2004 build
  55.                 echo 19041 or a later version.
  56.                 goto :exit_error
  57.         )
  58.         rem // alright, this distribution is on WSL2
  59. )
  60. echo ok
  61.  
  62. rem // make sure we're running from LOCAL STORAGE - if not, WSL2 will have relocated to $HOME and this will fuck everything up
  63. echo|set /p=Checking whether WSL knows the path to this very directory...
  64. wsl --distribution %WSL_DISTR% -- test ^"$^(pwd^)^" = ^"${HOME}^" && (
  65.         echo no
  66.         echo.
  67.         echo Error: you need to locate your working copy of this SVN repository on *local*
  68.         echo storage for the cross-build script to work consistently. The Windows Subsystem
  69.         echo for Linux cannot access Windows network shares.
  70.         echo Please relocate this repository on a local hard drive and try again.
  71.         goto :exit_error
  72. )
  73. echo yes
  74.  
  75. rem // make sure we have the required tools, install them if not
  76. set ETC_SUDOERS_PATCHED=0
  77. for %%i in (%REQUIRED_TOOLS%) do (
  78.         rem // tool syntax: "<executable>:<optional APT package name>"
  79.         rem // if package name is not specified, it defaults to <executable>
  80.         set REQUIRED_TOOL_AND_PACKAGE=%%i
  81.         for /f "tokens=1-2 delims=:" %%j in ('echo !REQUIRED_TOOL_AND_PACKAGE!') do (
  82.                 set REQUIRED_TOOL=%%j
  83.                 set REQUIRED_PACKAGE=%%k
  84.                 if "!REQUIRED_PACKAGE!"=="" set REQUIRED_PACKAGE=!REQUIRED_TOOL!
  85.         )
  86.         echo|set /p=Checking for the presence of !REQUIRED_TOOL! from APT package !REQUIRED_PACKAGE!...
  87.         wsl --distribution %WSL_DISTR% -- !REQUIRED_TOOL! --version > nul 2>&1 && (
  88.                 echo yes
  89.         ) || (
  90.                 echo no
  91.                 echo !REQUIRED_TOOL! needs installation. Attempting to install it.
  92.                 if "!ETC_SUDOERS_PATCHED!"=="0" (
  93.                         rem // allow ourselves to run any commands by patching /etc/sudoers. Do this once, and only if necessary. Also drop a note for posterity on why this was done.
  94.                         wsl --distribution %WSL_DISTR% -- sudo sh -c ^"grep -q '%%sudo  ALL=^(ALL^) NOPASSWD:ALL' /etc/sudoers ^|^| { echo ''; echo '# Pierre-Marie Baty -- added automatically on %DATE% by %~nx0 script'; echo '# This line allows members of the sudo group to execute any command WITHOUT the need to enter the root password'; echo '%%sudo  ALL=^(ALL^) NOPASSWD:ALL'; } ^>^> /etc/sudoers^"
  95.                         set ETC_SUDOERS_PATCHED=1
  96.                         rem // TEST if we have a working network from within WSL. It's no point waiting around if we don't. If it turns out we don't, jump to the relevant label
  97.                         echo Testing network connectivity...
  98.                         wsl --distribution %WSL_DISTR% -- ping -c 1 %WSL_SOURCE% > nul 2>&1 || goto :no_network
  99.                         rem // we MIGHT have a working network. Update APT cache before installing stuff, but just once. If it turns out we can't, jump to the relevant label
  100.                         wsl --distribution %WSL_DISTR% -- sudo apt-get -y update || goto :no_network
  101.                         rem // at this point we can consider that networking works from within WSL.
  102.                 )
  103.                 rem // attempt installation of this package from the network. If it fails, assume it's a network problem (cable unplugged?) and jump to the relevant label
  104.                 wsl --distribution %WSL_DISTR% sudo apt-get -y install !REQUIRED_PACKAGE! || goto :no_network
  105.         )
  106. )
  107. rem // if we reach here it means all the tools were successfully installed from the network, so jump to the next step
  108. goto :packages_installed
  109. :no_network
  110. rem // if we reach here, it means package installation from the network failed. Stop being nice and stuff them up Linux's ass with maximal pain from local storage.
  111. echo Looks like the network is unavailable. Nevermind the bollocks.
  112. echo Installing all the necessary packages at once...
  113. wsl --distribution %WSL_DISTR% sudo dpkg -i "../../Third-party software/%WSL_DISTR:-= % Debian packages for WSL2/"*.deb || (
  114.         echo.
  115.         echo Error: the required Linux tools %REQUIRED_TOOLS% can't be installed.
  116.         goto :exit_error
  117. )
  118. goto :packages_installed
  119. rem // nuff said.
  120.  
  121. :packages_installed
  122.  
  123. rem // setup the QNX SDP on the WSL side
  124.  
  125. rem // The build script initially recursively transferred the contents of $QNX_HOST and $QNX_TARGET to the WSL2 ext4 partition
  126. rem // when necessary using the Plan9 NTFS to ext4 bridge (9p file protocol) implemented by Microsoft to transfer files
  127. rem // from Windows to WSL2. The only problem with this is, and Microsoft admits it, that 9p is *catastrophically slow*.
  128. rem // See https://learn.microsoft.com/en-us/windows/wsl/compare-versions - And when Microsoft says "slow", hear "unusable".
  129. rem // To make this faster, here's what I do:
  130. rem //   1. fire up an archiver and create a SINGLE FILE archive of the directory hierarchy to copy
  131. rem //   2. hand the file over to WSL2
  132. rem //   3. unpack the archive in place - as it's much faster to migrate a single file than a folder hierarchy.
  133. rem // The only prerequisite shall be that the archive format be *operable with the tools at hand on both systems*.
  134. rem // By using the "usr\bin\tar.exe" utility from the QNX8 Win64 host SDP tools and piping the data through a WSL2 instance running
  135. rem // the Linux version of /usr/bin/tar to untar it directly at its location, we achieve 10x faster transfer speeds than 9p.
  136. rem // This is just ridiculous. I scoured the web for hours looking for an acceptable file transfer solution from Windows to WSL2
  137. rem // and it looks just like nobody found that one yet. Ah well...
  138.  
  139. rem // see if the SDP needs to be copied at all. Only do this when the modification time of the SDP directory on Windows is more recent than the one on Linux.
  140. rem // So test for the presence of the symlinks state file as it's the last file that's created (this ensures a complete copy), then check for the directory mtimes.
  141. rem // NOTE: on WSL2, the QNX SDK will always be copied to $HOME, regardless of what xdg-user-dir DESKTOP says.
  142. echo|set /p=Checking if the %QNXSDK_DIRNAME% directory is present in WSL and up to date...
  143. wsl --distribution %WSL_DISTR% -- test ! -f "${HOME}/%QNXSDK_DIRNAME%/.symlinks-state" -o "../%QNXSDK_DIRNAME%" -nt "${HOME}/%QNXSDK_DIRNAME%" && (
  144.         echo no
  145.  
  146.         rem // copy needed - cleanup and create the directories we'll need in $HOME to accomodate the QNX SDK. We want the Linux host tools, and the QNX target sysroot files
  147.         echo|set /p=Preparing to copy QNX8 SDK files to WSL2 ext4 filesystem...
  148.         wsl --distribution %WSL_DISTR% -- rm -rf "${HOME}/%QNXSDK_DIRNAME%"; mkdir -p "${HOME}/%QNXSDK_DIRNAME%/host" "${HOME}/%QNXSDK_DIRNAME%/target" 2>nul
  149.         echo done
  150.  
  151.         rem // transfer the QNX SDK host files: tar on Windows, pipe to WSL2, untar on Linux - or die
  152.         echo|set /p=Deploying QNX8 SDK Linux host files to WSL2 ext4 filesystem ^(this can take some time^)...
  153.         "..\%QNXSDK_DIRNAME%\host\win64\x86_64\usr\bin\tar.exe" -c --directory="..\%QNXSDK_DIRNAME%\host" linux | wsl --distribution %WSL_DISTR% -- tar -x --directory="${HOME}/%QNXSDK_DIRNAME%/host" || ( echo failed & goto :exit_error )
  154.         echo done
  155.  
  156.         rem // Windows has absolutely no notion of UNIX permissions. The best we can do here is to arbitrarily set the executable flags on relevant parts of the migrated tree.
  157.         echo|set /p=Setting executable permissions to QNX8 SDK toolchain files...
  158.         wsl --distribution %WSL_DISTR% -- chmod -R +x "${HOME}/%QNXSDK_DIRNAME%/host/linux/x86_64/usr/bin" "${HOME}/%QNXSDK_DIRNAME%/host/linux/x86_64/usr/lib/gcc" || goto :exit_error
  159.         echo done
  160.  
  161.         rem // transfer the QNX SDK target files: tar on Windows, pipe to WSL2, untar on Linux - or die
  162.         echo|set /p=Deploying QNX8 SDK target sysroot files to WSL2 ext4 filesystem ^(this WILL take some time^)...
  163.         "..\%QNXSDK_DIRNAME%\host\win64\x86_64\usr\bin\tar.exe" -c --directory="..\%QNXSDK_DIRNAME%\target" qnx | wsl --distribution %WSL_DISTR% -- tar -x --directory="${HOME}/%QNXSDK_DIRNAME%/target" || ( echo failed & goto :exit_error )
  164.         echo done
  165.  
  166.         rem // setup the toolchain symlinks
  167.         echo Setting up the QNX SDP platform-specific symlinks...
  168.         "..\%QNXSDK_DIRNAME%\host\win64\x86_64\usr\bin\tar.exe" -c --directory="..\%QNXSDK_DIRNAME%" symlinks.sh | wsl --distribution %WSL_DISTR% -- tar -x --directory="${HOME}/%QNXSDK_DIRNAME%" || ( echo failed & goto :exit_error )
  169.         wsl --distribution %WSL_DISTR% -- cd "${HOME}/%QNXSDK_DIRNAME%" ^&^& find . -name symlinks.lst -exec ./symlinks.sh {} create $1 \; ^&^& printf 'present-v2' ^> "${HOME}/%QNXSDK_DIRNAME%/.symlinks-state" || goto :exit_error
  170. )
  171. echo ok
  172.  
  173. rem // now chain-call the POSIX Bourne shell build script
  174. echo Running POSIX build script...
  175. wsl --distribution %WSL_DISTR% -- ./cross-build.sh || goto :exit_error
  176.  
  177. rem // at this point, the story is supposed to have ended well.
  178. rem // Keep calm, and I'll tell you another one tomorrow.
  179. echo.
  180. echo The build ended successfully.
  181. goto :exit_success
  182.  
  183.  
  184. :install_wsl
  185.         echo Installing the Windows Subsystem for Linux...
  186.         echo  __________________________________________________________________________
  187.         echo ^|                                                                          ^|
  188.         echo ^| NOTE: please define a *non-root* Linux user name and password when asked ^|
  189.         echo ^|       ^(for example: 'utilisateur' / 'utilisateur'^)                       ^|
  190.         echo ^|       then type 'exit' at the Linux shell ^(green prompt^) to continue.    ^|
  191.         echo ^|__________________________________________________________________________^|
  192.         echo.
  193.         wsl --install --distribution %WSL_DISTR% || (
  194.                 echo Error: you need at least a version of Windows 10 which has the "wsl" command.
  195.                 echo Please upgrade your Windows operating system to Windows 10 version 2004 build
  196.                 echo 19041 or a later version.
  197.                 goto :exit_error
  198.         )
  199.         echo The Windows Subsystem for Linux was successfully installed with the %WSL_DISTR% distribution.
  200.         echo Action required: please reboot your computer if requested and run this script again.
  201.         goto :exit_success
  202.  
  203. :exit_error
  204. rem // failure exit
  205. echo.
  206. pause
  207. exit /b 1
  208.  
  209. :exit_success
  210. rem // successful exit
  211. echo.
  212. pause
  213. exit /b 0
  214.