Because, why not?
Playing around with WSL2, I figured it could be used to make one-off build containers. In a similar way I usually use docker.
For example, building TDLib for Telegram Messenger.
My run.cmd
is simple:
@echo off
wsl --import alpine-build .\VM alpine-minirootfs-3.12.0-x86_64.tar.gz
wsl -d alpine-build /bin/sh /mnt/e/Temp/TDLib/build.sh
wsl --unregister alpine-build
- Install alpine distribution by running
wsl --import
- Execute the build script
- Unregister the distribution
Build script, build.sh
, is made using TDLib Build instrunction generator, with the addition of the OUT_DIR
variable just to make it easier.
OUT_DIR=/mnt/e/Temp/TDLib/lib
cd ~
apk update
apk upgrade
apk add --update alpine-sdk linux-headers git zlib-dev openssl-dev gperf php php-ctype cmake
git clone https://github.com/tdlib/td.git
cd td
git checkout v1.6.0
rm -rf build
mkdir build
cd build
export CXXFLAGS=""
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=$OUT_DIR ..
cmake --build . --target install
cd ..
cd ..
ls -l $OUT_DIR
Running it and it works.
PS E:\Temp\TDLib> .\run.cmd
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
v3.12.0-214-g4076381e49 [http://dl-cdn.alpinelinux.org/alpine/v3.12/main]
v3.12.0-213-gfedcac4c0f [http://dl-cdn.alpinelinux.org/alpine/v3.12/community]
OK: 12749 distinct packages available
(1/6) Upgrading musl (1.1.24-r8 -> 1.1.24-r9)
<snip>
-- The CXX compiler identification is GNU 9.3.0
-- The C compiler identification is GNU 9.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
<snip>
-- Configuring done
-- Generating done
-- Build files have been written to: /root/td/build
Scanning dependencies of target tdsqlite
[ 0%] Building C object sqlite/CMakeFiles/tdsqlite.dir/sqlite/sqlite3.c.o
[ 0%] Linking C static library libtdsqlite.a
[ 0%] Built target tdsqlite
<snip>
Scanning dependencies of target bench_queue
[100%] Building CXX object benchmark/CMakeFiles/bench_queue.dir/bench_queue.cpp.o
[100%] Linking CXX executable bench_queue
[100%] Built target bench_queue
Install the project...
-- Install configuration: "Release"
-- Installing: /mnt/e/Temp/TDLib/lib/lib/libtdjson.so.1.6.0
-- Installing: /mnt/e/Temp/TDLib/lib/lib/libtdjson.so
-- Installing: /mnt/e/Temp/TDLib/lib/lib/libtdjson_static.a
-- Installing: /mnt/e/Temp/TDLib/lib/lib/libtdjson_private.a
<snip>
total 0
drwxrwxrwx 1 root root 512 Aug 7 14:03 include
drwxrwxrwx 1 root root 512 Aug 7 14:03 lib
Unregistering...
PS E:\Temp\TDLib>
Not as versatile as docker run
but does the job.
Using differencing disks
Using differencing disks, I can have all build tools installed in the base vhdx and spawn "build container" just for a single build.
For example, based on above, I've created base
PS E:\Temp> wsl --import Alpine-BuildBase E:\WSL2\Alpine-BuildBase E:\WSL2\alpine-minirootfs-3.12.0-x86_64.tar.gz
And installed everything I need
apk update
apk upgrade
apk add --update alpine-sdk linux-headers git zlib-dev openssl-dev gperf php php-ctype cmake
Now my build.sh
omits tools installation and looks like:
OUT_DIR=/mnt/e/Temp/TDLib/lib
cd ~
git clone https://github.com/tdlib/td.git
cd td
git checkout v1.6.0
rm -rf build
mkdir build
cd build
export CXXFLAGS=""
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=$OUT_DIR ..
cmake --build . --target install
cd ..
cd ..
ls -l $OUT_DIR
And the final part, run.ps1
PowerShell script that will:
- Create differencing vhdx
- Make a registry key for the linux distribution "container"
- Execute the build script
- Unregister the distribution
#Must be run as an Administrator
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
exit;
}
$DISTRO_NAME = "alpine-build"
#Create a new differencing VHD
New-Item -Path VM -ItemType Directory -Force | Out-Null
New-VHD -ParentPath E:\WSL2\Alpine-BuildBase\ext4.vhdx -Path .\VM\ext4.vhdx -Differencing -BlockSizeBytes 1048576
#Add a registry key
$guid = New-Guid
$RegKey = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\" + $guid.ToString("B")
New-Item -Path $RegKey
New-ItemProperty -Path $RegKey -Name BasePath -PropertyType String -Value $PWD\VM | Out-Null
New-ItemProperty -Path $RegKey -Name DefaultUid -PropertyType DWord -Value 0 | Out-Null
New-ItemProperty -Path $RegKey -Name DistributionName -PropertyType String -Value $DISTRO_NAME | Out-Null
New-ItemProperty -Path $RegKey -Name Flags -PropertyType DWord -Value 15 | Out-Null
New-ItemProperty -Path $RegKey -Name State -PropertyType DWord -Value 1 | Out-Null
New-ItemProperty -Path $RegKey -Name Version -PropertyType DWord -Value 2 | Out-Null
#Run the build script
wsl -d $DISTRO_NAME /bin/sh /mnt/e/Temp/TDLib/build.sh
#Unregister the distribution
wsl --unregister $DISTRO_NAME
#Pause
Read-Host -Prompt "Press Enter key to continue"
Just testing
To make sure above script works as expected instead of running the build script (line 25 above) I can swap it with
wsl -d $DISTRO_NAME /bin/sh -c "date && cat /etc/*-release"
Result is
ComputerName : PC123
Path : E:\Temp\TDLib\VM\ext4.vhdx
VhdFormat : VHDX
VhdType : Differencing
FileSize : 6291456
Size : 274877906944
MinimumSize :
LogicalSectorSize : 512
PhysicalSectorSize : 4096
BlockSize : 1048576
ParentPath : E:\WSL2\Alpine-BuildBase\ext4.vhdx
DiskIdentifier : A96ADE57-4838-48EA-97A9-DE02790ADCB4
FragmentationPercentage :
Alignment : 1
Attached : False
DiskNumber :
IsPMEMCompatible : False
AddressAbstractionType : None
Number :
Property : {}
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\{4
e9ced54-7d28-48d2-92de-1df93ddc55a9}
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss
PSChildName : {4e9ced54-7d28-48d2-92de-1df93ddc55a9}
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry
PSIsContainer : True
SubKeyCount : 0
View : Default
Handle : Microsoft.Win32.SafeHandles.SafeRegistryHandle
ValueCount : 0
Name : HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\{4e9ced54-7d28-48d2-92de-1df93ddc55a9}
Fri Aug 7 15:27:17 UTC 2020
3.12.0
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.0
PRETTY_NAME="Alpine Linux v3.12"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
Unregistering...
Press Enter key to continue:
Conclusion
I'm not sure if this has a practical value. Maybe in scenarios where it is easier to have a single file virtual disk rather than a docker container stored in some registry. But it was an interesting concept to explore. Let me know if you find it useful.
Top comments (0)