Difference between revisions of "WebAssembly/Compiler"

From Lazarus wiki
Jump to navigationJump to search
(Removed optional stuff to reduce potential for confusion.)
(Link to a runnable demo.)
Line 29: Line 29:
 
== Obtaining the compiler sources ==
 
== Obtaining the compiler sources ==
  
The WebAssembly compiler target is part of 'main' branch of the GitLab FPC source repo. Get the source:
+
The WebAssembly compiler target is part of the 'main' branch of the GitLab FPC source repo. Get the source:
 
  % git clone https://gitlab.com/freepascal.org/fpc/source.git fpc
 
  % git clone https://gitlab.com/freepascal.org/fpc/source.git fpc
  
Line 73: Line 73:
 
See [[WebAssembly/Roadmap]] for details.
 
See [[WebAssembly/Roadmap]] for details.
  
Compiled WASI binaries work with wasmtime version 0.23.0 or in the browser by opening:
+
Compiled WASI binaries work with modern web browsers, although they require the web browser to provide the necessary WASI runtime services. See [https://github.com/PierceNg/wasm-demo wasm-demo] for an example implementing Conway's Game of Life. In the example, WASI functions are implemented in Javascript; the functions themselves do nothing, because the Pascal code implementing Life does not use those functions - they are only 'required' because of compiler-generated linkages.
 
 
https://webassembly.sh/
 
 
 
and drag and dropping the .wasm binary directly into the browser window.
 
  
 
=== Embedded target ===
 
=== Embedded target ===

Revision as of 13:48, 1 April 2022

Instructions

Prerequisites

The linker wasm-ld from the LLVM project. LLVM 11.0 and 12.0.1 are known to work.

Fedora

Development was done, using the Fedora packages llvm-11.0.0-1.fc33.x86_64 and lld-11.0.0-1.fc33.x86_64.

Ubuntu

Tested on Ubuntu 20.04. wasm-ld is part of package lld-12. Install it and set necessary symlinks:

% sudo apt install lld-12
% ln -sf /usr/lib/llvm-12/bin/wasm-ld ~/bin/wasm32-wasi-wasm-ld
% ln -sf /usr/lib/llvm-12/bin/wasm-ld ~/bin/wasm32-embedded-wasm-ld

Note: This assumes you have a $HOME/bin directory and it is in PATH.

MacOS

Tested on MacOS Catalina with LLVM 11. For MacPorts, wasm-ld is part of package llvm-11. Install it and set necessary symlink:

% sudo port install llvm-11
% ln -sf /opt/local/bin/wasm-ld-mp-11 ~/bin/wasm32-wasi-wasm-ld
% ln -sf /opt/local/bin/wasm-ld-mp-11 ~/bin/wasm32-embedded-wasm-ld

Note: This assumes you have a $HOME/bin directory and it is in PATH.

Obtaining the compiler sources

The WebAssembly compiler target is part of the 'main' branch of the GitLab FPC source repo. Get the source:

% git clone https://gitlab.com/freepascal.org/fpc/source.git fpc

Enter the sources directory:

% cd fpc

Supported targets

If you are new to building the compiler, see Installing the Free Pascal Compiler and Cross compiling.

WASI - The WebAssembly System Interface

On Ubuntu and MacOS, to build the compiler and FPC units for the WASI target:

% make all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc

On Ubuntu and MacOS, after building, install (using INSTALL_PREFIX to specify a destination within your home directory):

% make crossinstall OS_TARGET=wasi CPU_TARGET=wasm32 INSTALL_PREFIX=$HOME/fpcwasm

On Ubuntu and MacOS, make a link to the cross compiler executable ppcrosswasm32:

% ln -sf ~/fpcwasm/lib/fpc/3.3.1/ppcrosswasm32 ~/bin/ppcrosswasm32

Note: This assumes you have a $HOME/bin directory and it is in PATH.

WASI is a modular system interface for WebAssembly. It allows creating portable and secure programs that can run in a sandboxed command-line environment or in the browser. See the WASI website for more information.

The following units have been ported for the WASI target:

  • system
  • objpas
  • iso7185
  • ctypes
  • strings
  • wasiapi - interface for the WASI API

Additionally, these units compile, but are not yet fully functional and/or tested very well:

  • dos
  • sysutils
  • classes
  • math
  • fgl

See WebAssembly/Roadmap for details.

Compiled WASI binaries work with modern web browsers, although they require the web browser to provide the necessary WASI runtime services. See wasm-demo for an example implementing Conway's Game of Life. In the example, WASI functions are implemented in Javascript; the functions themselves do nothing, because the Pascal code implementing Life does not use those functions - they are only 'required' because of compiler-generated linkages.

Embedded target

The Embedded target is primarily used for embedded systems (not a browser), without an operating system. However, it also happens to be a perfect fit for creating WebAssembly modules that don't use any particular operating system-like API.

On Ubuntu and MacOS, to build the compiler and FPC units for the 'embedded' target:

% make all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc

On Ubuntu and MacOS, after building, install (using INSTALL_PREFIX to specify a destination within your home directory):

% make crossinstall OS_TARGET=embedded CPU_TARGET=wasm32 INSTALL_PREFIX=$HOME/fpcwasm

On Ubuntu and MacOS, if you have not built and installed the WASI cross compiler, then make a link to the cross compiler executable ppcrosswasm32;

% ln -sf ~/fpcwasm/lib/fpc/3.3.1/ppcrosswasm32 ~/bin/ppcrosswasm32

Note: This assumes you have a $HOME/bin directory and it is in PATH.

Using the compiler

If you have installed the cross compiler and units into $HOME/fpcwasm (as per the commands used above), then you need to configure $HOME/.fpc.cfg so that the cross compiler can locate its units.

For Ubuntu, add these lines:

#ifdef cpuwasm32
-Fu/home/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/*
-Fu/home/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/rtl
#endif

For MacOS, add these lines:

#ifdef cpuwasm32
-Fu/Users/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/*
-Fu/Users/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/rtl
#endif

Lazarus

When you create a new Lazarus project for a wasm program you can use the Simple Program template and then adjust the Project / Project Options / Compiler Options:

  • Paths / Target file name: Lazarus 2.3.0 (Dec 28th 2021) appends the required .wasm file extension to the output file. To support older IDEs disable Apply conventions and set <programname>.wasm.
  • Config and Target / Target platform:
    • Target OS: Wasi
    • Target CPU: wasm32
  • Debugging / Generate info for debugger: disable (Dec 28th 2021: otherwise you will get can't find unit linfodwrf)
  • Compiler Commands / Compiler / Command: If you are using different fpc versions / folders you can here set the path to ppcrosswasm32 (e.g. Linux: /usr/lib/fpc/3.3.1/ppcrosswasm32)

See Also