Sign in Join
Wiki copytemporary

Windows Subsystem for Linux

Microsoft introduced a certain compatibility functionality in order to run ELF binaries under Windows 10.

WSL1

WSL1 is implemented as Microsoft developed Linux-kernel-compatible execution environment. This is not an actual Linux kernel, but only its substitute, which provides the most common functionality.

The functionality is ENOUGH to run FPC without modifications.

Installing WSL and FPC

Microsoft provides a number of Linux distros through Microsoft Store application. The following steps are using Ubuntu 16.4 LTS distro:

You can run control panel (press Win+R type in "control" and press enter) and search for "windows features" in order to bring the dialog up. The link is also available in "Add and Remove programs" section of control panel).

Note: WSL1 only requires "Windows subsystem for Linux" to be installed.

"Virtual Machine Platform" is only requires for WSL2.

Run the following commands on Linux command-line

sudo apt-get update
sudo apt-get upgrade

Running the test app from Windows

The "wsl" utility can be used to run Linux (x86_64) targets on Windows. If you used the example above to compile the application, then you should be able to run as following, from Windows command-line

cd c:\testrun
wsl ./testrun

output

hello world

Running (linux) FPC from Windows

Similar to the sample application, FPC itself can also be ran from Windows.

Here's an example create a folder in Windows, and create a file there test.pas. Edit the file (i.e. using notepad) and put the following code:

pascal
procedure RunLoop;
var
  i : integer;
begin
  for i:=1 to 10 do
    write(i,' ');
  writeln;
end;

begin 
  {$ifdef mswindows}
  writeln('windows');
  {$endif}
  {$ifdef linux}
  writeln('linux');
  {$endif}
  writeln('hello world');
  writeln(sizeof(Pointer));
  RunLoop;
end.

Run the following commands from command line. Note, that the use of "WSL" is critical (otherwise you'll get a windows binary). (Running the command-line requires both WSL installed and FPC for the distro installed)

wsl fpc ./test
wsl ./test

You should see in command-line the following output:

linux
hello world
8
1 2 3 4 5 6 7 8 9 10

Indicating the binary was built for linux 64-bit system

Running (linux) Gdb from Windows

WSL1 provides enough functionality in order for GDB to run.

However, GDB itself is not installed by default (on Ubuntu 16.4 distro) and needs to be installed prior to use

wsl sudo apt-get install gdb

Recompile the existing sample program with Dwarf2 enabled.

wsl fpc -gw2 test.pas

(you should see the size of the executable increasing)

Run GDB for the compiledexecutable.

wsl gdb test

you should see:

C:\testbuild>wsl gdb test
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.

at the initial-load place a breakpoint within the runloop procedure:

(gdb) b test.pas:6

resulting in:

Breakpoint 1 at 0x4001e6: file test.pas, line 6.

and proceed with the execution:

(gdb) r
Starting program: /mnt/c/testbuild/test
linux
hello world
8\

Breakpoint 1, RUNLOOP () at test.pas:6
6           write(i,' ');
(gdb) 

at this point you can do all typical Gdb actions you need to do. I.e. researching stack:

(gdb) bt
#0  RUNLOOP () at test.pas:6
#1  0x00000000004002fa in main () at test.pas:19

or terminating the exectuion

(gdb) q

WSL2

WSL2 is a different approach, that's implemented using an actual Linux kernel running in a virtual machine. Namely the entire Linux kernel functionality is available (... and the sky is limit!). Microsoft also addressed some performance issues when writing files to NTFS.

Installing

wsl --set-version Ubuntu-16.04 2

if you running into troubles switching to Version 2, see below.

The process of setting a version takes about a couple of minutes so be patient.

Unable to switch to version 2

If you're getting this error

The requested operation could not be completed due to a virtual disk system limitation. 
Virtual hard disk files must be uncompressed and unencrypted and must not be sparse.

There are 2 ways you should be able to resolve this:

%localappdata%\Packages\CanonicalGroupLimited.UbuntuonWindows_xxxxxxx

fsutil behavior set disableencryption 1
fsutil behavior set disablecompression 1

See more at: https://github.com/microsoft/WSL/issues/4103

If you're getting an error of Timeout - try to restart the PC.

Using FPC

The process of installation and use of FPC is identical to the described in WSL1. (The installation isidentical to an actual Linux or Linux running in a 3d party Virtual Machine)

No additional changes are needed for FPC itself in order to run and compile from WSL2.

Using GDB

In general the installation of GDB is similar to WSL1.

It seems like there were changes in pipe handling in Gdb, compared to WSL1.

Thus running

 wsl gdb application_name

would still work, but sometimes pipe communication might fail and you would not see a GDB prompt.

On the other hand, if a user tries to use gdb directly from wsl.exe shell, it works just fine.

Running ELF binaries from Windows app

Any windows application can run ELF binary using "wsl.exe".

Windows itself would not recognize ELF executable as an executable. Thus an attempt to open it would make Windows prompt the user for the host application to be specified. There's not special Windows API yet to run them. So far the only way of running an ELF binary is using "wsl.exe".

That means that a desired Linux distro(s) needs to be installed. (and preferably one of them selected as default)

Using WSL.exe

Running ELF binary with WSL.exe requires an explicit call to "wsl.exe" and passing ELF binary as a parameter, as well as any additional parameters.

That typically involves creating a process with StdOut/StrErr redirected to pipes (either by using WinAPI directory or TProcess).

Caveat: there seems to be some special handling of Pipe-redirected output in WSL itself. The launched WSL might not terminate until it receives something on the input buffer. It might also skip some output, if the launching application is "sleeping" for too long. Thus the typical wait for output period should be minimal.

pascal
  p := TProcess.Create(nil);
  try
    p.Executable := 'wsl.exe'; 
    p.Parameters.Add('ls'); // running ls utility 
    p.Parameters.Add('-l'); // with -l parameter
    p.Options := [poUsePipes];

    while (p.Running) or (p.Output.NumBytesAvailable > 0) do
    begin
      if p.Running and (p.Output.NumBytesAvailable = 0) then
      begin
        s:=#0; // writing anything to the input
        p.Input.Write(s, length(s));
        Sleep(1); // the shortest sleep possible
      end;

      sz := p.Output.NumBytesAvailable;
      if sz>0 then begin
        SetLength(s, sz);
        sz := p.Output.Read(s[1], sz);
        if sz < length(s) then SetLength(s, sz);
        write(s);
      end;
   end;

  finally
    p.Free;
  end;

It also doesn't seem that WSL is returning the exit code back.

One can refer to the full code example of "wslwrap" application: https://github.com/skalogryz/wslwrap

Lazarus

Using Lazarus from WSL

WSL itself comes without graphical support by default. Yet it should be possible to install X-Windows server on Windows 10 machine itself, and configure WSL distro to use Windows 10 as its windows server.

That also should open an option for developing and debugging Linux GUI applications using WSL.

Using WSL FPC and GDB from Windows

As long as Lazarus is capable of "prefixing" every FPC (and Gdb) commands with "wsl" - forcing the Windows Subsystem for Linux to execute, it should be capable of producing native (command-line) executables.

It's likely Lazarus on Windows would also need to substitute the proper file path when dealing with WSL-ed projects.

Quick and Dirty - Using WSL FPC from Windows

Dislaimer: the proper solution might require additional work on IDE side. While the compiler doesn't need to be changed at all. It's possible to create a WSL compiler in order to by-pass Lazarus limitations, without a need of building a special cross-compiler.

The such name has two purposes:

1) it starts with "ppc". Lazarus verifies the compiler executable to start with either "ppc" or "fpc", otherwise it would produce (a lot of annoying) warnings

2) "_fpc" part enforces the use of "fpc" executable on WSL side (this is "wslwrap" feature)

The IDE would complain about "fpc.cfg" missing - ignore it.

begin 
  writeln('hello world');
end.

Target OS = Linux

Target CPI = x86_64

In order to rollback, simply restore the original FPC configuration in the IDE option.

See Also


From the Free Pascal wiki, page "Windows Subsystem for Linux", as it stood on 2019-12-14 after a change by Bart, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 1, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.