Difference between revisions of "WebAssembly/Compiler"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed macOS capitalisation throughout)
 
(37 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== Instructions ==
+
= Prerequisites =
  
=== Prerequisites ===
+
The linker ''wasm-ld'' from the LLVM project. LLVM 11.0 and 12.0.1 are known to work.
  
The ''llvm-mc'' assembler and ''wasm-ld'' linker. These are the assembler and linker from the LLVM project.
+
== Fedora ==
  
=== Obtaining the compiler sources ===
+
Development was done, using the Fedora packages llvm-11.0.0-1.fc33.x86_64 and lld-11.0.0-1.fc33.x86_64.
  
Get the sources:
+
== Ubuntu ==
  
  svn checkout https://svn.freepascal.org/svn/fpc/branches/wasm/ fpc-wasm
+
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
  
enter the directory:
+
Note: This assumes you have a $HOME/bin directory and it is in PATH.
cd fpc-wasm
 
  
=== Supported targets ===
+
== macOS ==
  
==== WASI ====
+
=== Catalina ===
 +
Tested on '''macOS Catalina''' with LLVM 11. For [https://www.macports.org MacPorts] ''wasm-ld'' is part of package ''llvm-11''; upon installation it exists as ''wasm-ld-mp-11''. Install the package and set necessary symlinks:
 +
% 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
  
[https://wasi.dev/ WASI] is a modular system interface for WebAssembly. It allows creating portable and secure programs that can run in a sandboxed command-line environment. See the WASI website for more information.
+
Note: This assumes you have a $HOME/bin directory and it is in PATH.
  
To build the compiler for the WASI target:
+
=== Monterey ===
 +
Tested on '''macOS Monterey 12.5.1''': wasm-ld is part of the official clang release for macOS:
 +
https://releases.llvm.org/download.html#11.1.0
  
make all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
+
Unpack it. When running wasm-ld, macOS might warn, that ldd cannot be verified. Open the System Preferences / Security / General. There should be ldd, unlock, then click Open Anyway.
  
Currently, it reaches the point, where it fails with this error:
+
== Windows 10 ==
  
globals.pas(40,7) Fatal: Can't find unit sysutils used by globals
+
Tested on Windows 10 Home 21H2. Download the [https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.1 LLVM 12.0.1] 64-bit Windows installer. You are encouraged to verify the GPG signature on the installer. As administrator, run the installer. Let's say you installed into C:\llvm. Enable Windows 'developer mode' if you have not done so. Then set necessary symlinks:
Fatal: Compilation aborted
+
  C:\> cd llvm\bin
 +
  C:\llvm\bin> mklink wasm32-wasi-wasm-ld.exe wasm-ld.exe
 +
  C:\llvm\bin> mklink wasm32-embedded-wasm-ld.exe wasm-ld.exe
  
This is because the sysutils hasn't been ported to the WASI target, yet. If compilation reaches this point, you can still compile 'Hello, world!'. The following units have been ported for the WASI target:
+
Add C:\llvm\bin to your PATH.
  
* system
+
= Obtaining the compiler sources =
* objpas
 
* ctypes
 
* strings
 
* wasiapi - interface for the WASI API
 
  
==== Embedded target ====
+
== Linux and macOS ==
make all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
 
  
=== Using the compiler ===
+
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
  
Hint: If your fpc.cfg has
+
Enter the sources directory:
<pre>
+
% cd fpc
#IFDEF FPC_CROSSCOMPILING
+
 
#IFDEF NEEDCROSSBINUTILS
+
== Windows ==
  -XP$FPCTARGET-
+
 
#ENDIF
+
The WebAssembly compiler target is part of the 'main' branch of the GitLab FPC source repo. Get the source:
#ENDIF
+
C:\Users\OnlyMe> git clone https://gitlab.com/freepascal.org/fpc/source.git fpc
</pre>
+
 
 +
Enter the sources directory:
 +
C:\Users\OnlyMe> cd fpc
 +
 
 +
= Building and installing =
 +
 
 +
If you are new to building the compiler, see [[Installing the Free Pascal Compiler]] and [[Cross compiling]].
 +
 
 +
FPC supports two WebAssembly compilation targets: WASI and embedded.
 +
 
 +
== Compilation target: WASI ==
 +
 
 +
=== Linux and macOS ===
 +
 
 +
Build the compiler and FPC units for the WASI target:
 +
% make clean all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
 +
 
 +
Then, install, using INSTALL_PREFIX to specify a destination within your home directory:
 +
% make crossinstall OS_TARGET=wasi CPU_TARGET=wasm32 INSTALL_PREFIX=$HOME/fpcwasm
 +
 
 +
Note: On macOS you might have to add ''-XR/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk'' to ''OPT''.
 +
 
 +
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.
 +
 
 +
=== Windows ===
 +
 
 +
Make sure the Windows native compiler fpc.exe and the FPC-bundled make.exe are in your PATH. Especially ensure that the FPC make.exe comes first in your PATH; using another make.exe (such as the one installed by Delphi) that happens to be ahead in PATH may not work.
 +
 
 +
Build the compiler and FPC units for the WASI target:
 +
C:\Users\OnlyMe\fpc> make clean all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
 +
 
 +
Then, install, using INSTALL_PREFIX to specify a destination folder:
 +
C:\Users\OnlyMe\fpc> make crossinstall OS_TARGET=wasi CPU_TARGET=wasm32 INSTALL_PREFIX=c:\fpcwasm PP=fpc
 +
 
 +
Add C:\fpcwasm\bin\x86_64-win64 to your PATH to easily run the compiler ''ppcrosswasm32.exe''.
 +
 
 +
== Compilation target: Embedded  ==
 +
 
 +
=== Linux and macOS ===
 +
 
 +
Build the compiler and FPC units for the 'embedded' target:
 +
% make clean all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
 +
 
 +
Then, install, using INSTALL_PREFIX to specify a destination within your home directory:
 +
% make crossinstall OS_TARGET=embedded CPU_TARGET=wasm32 INSTALL_PREFIX=$HOME/fpcwasm
 +
 
 +
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.
 +
 
 +
=== Windows ===
 +
 
 +
Make sure the Windows native compiler fpc.exe and the FPC-bundled make.exe are in your PATH. Especially ensure that the FPC make.exe comes first in your PATH; using another make.exe (such as the one installed by Delphi) that happens to be ahead in PATH may not work.
  
Enclose it in '''#IFNDEF CPUWASM32''' :
+
Build the compiler and FPC units for the 'embedded' target:
<pre>
+
C:\Users\OnlyMe\fpc> make clean all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
#IFDEF FPC_CROSSCOMPILING
 
#IFDEF NEEDCROSSBINUTILS
 
#ifndef cpuwasm32
 
  -XP$FPCTARGET-
 
#endif
 
#ENDIF
 
#ENDIF
 
</pre>
 
  
Otherwise, you have to create symlinks wasm-wasm-wasmld to wasmld, and wasm-wasm-wasmtool to wasmtool.
+
Then, install, using INSTALL_PREFIX to specify a destination folder:
 +
C:\Users\OnlyMe\fpc> make crossinstall OS_TARGET=embedded CPU_TARGET=wasm32 INSTALL_PREFIX=c:\fpcwasm PP=fpc
  
==wasm-demo==
+
Add C:\fpcwasm\bin\x86_64-win64 to your PATH if you have not already done so.
Wasm-demo is a Pascal WebAssembly demo project, ported Google's C WebAssembly example (https://codelabs.developers.google.com/codelabs/web-assembly-intro)
 
  
You follow these steps in order to get the demo project working:
+
= Using the compiler =
  
1. Get the project sources: https://github.com/skalogryz/wasm-demo
+
For Linux and macOS, 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.
  
===Using in webassembly.studio===
+
For Ubuntu, add these lines:
2. Run the wasm compiler against lyff.pas, but request the assembler file to be kept
+
<pre>
  pp -a lyff.pas
+
#ifdef cpuwasm32
Webassembly.studio accepts the assembler file and would compile it on the server side.
+
-Fu/home/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/*
 +
-Fu/home/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/rtl
 +
#endif
 +
</pre>
  
3. open up  https://webassembly.studio and select "Create empty Wat Project". The project will consist of:
+
For macOS, add these lines:
:main.html
+
<pre>
:main.js
+
#ifdef cpuwasm32
:main.wat
+
-Fu/Users/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/*
All files of the project can be edited through the web interface.
+
-Fu/Users/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/rtl
 +
#endif
 +
</pre>
  
4. Copy and paste the contents of the following files:
+
On Windows, if you have set C:\fpcwasm\bin\x86_64-win64 directory in your PATH, then ''ppcrosswasm32.exe'' will be able to find its units.  
: (compiled) lyff.wat to main.wat.
 
: wasm-demo\webassembly.studio\main.html to main.html
 
: wasm-demo\webassembly.studio\main.js to main.js
 
  
Note: every time you copy and paste, don't forget to press "SAVE" button (on the right side of the web interface)
+
= Using the compiler with Lazarus =
  
5. once all files are update, hit "Build and Run"
+
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==
+
=See Also=
 
*[[WebAssembly]]
 
*[[WebAssembly]]
 
[[Category:WebAssembly]]
 
[[Category:WebAssembly]]

Latest revision as of 12:13, 8 September 2022

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

Catalina

Tested on macOS Catalina with LLVM 11. For MacPorts wasm-ld is part of package llvm-11; upon installation it exists as wasm-ld-mp-11. Install the package and set necessary symlinks:

% 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.

Monterey

Tested on macOS Monterey 12.5.1: wasm-ld is part of the official clang release for macOS: https://releases.llvm.org/download.html#11.1.0

Unpack it. When running wasm-ld, macOS might warn, that ldd cannot be verified. Open the System Preferences / Security / General. There should be ldd, unlock, then click Open Anyway.

Windows 10

Tested on Windows 10 Home 21H2. Download the LLVM 12.0.1 64-bit Windows installer. You are encouraged to verify the GPG signature on the installer. As administrator, run the installer. Let's say you installed into C:\llvm. Enable Windows 'developer mode' if you have not done so. Then set necessary symlinks:

 C:\> cd llvm\bin
 C:\llvm\bin> mklink wasm32-wasi-wasm-ld.exe wasm-ld.exe
 C:\llvm\bin> mklink wasm32-embedded-wasm-ld.exe wasm-ld.exe

Add C:\llvm\bin to your PATH.

Obtaining the compiler sources

Linux and macOS

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

Windows

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

C:\Users\OnlyMe> git clone https://gitlab.com/freepascal.org/fpc/source.git fpc

Enter the sources directory:

C:\Users\OnlyMe> cd fpc

Building and installing

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

FPC supports two WebAssembly compilation targets: WASI and embedded.

Compilation target: WASI

Linux and macOS

Build the compiler and FPC units for the WASI target:

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

Then, install, using INSTALL_PREFIX to specify a destination within your home directory:

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

Note: On macOS you might have to add -XR/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk to OPT.

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.

Windows

Make sure the Windows native compiler fpc.exe and the FPC-bundled make.exe are in your PATH. Especially ensure that the FPC make.exe comes first in your PATH; using another make.exe (such as the one installed by Delphi) that happens to be ahead in PATH may not work.

Build the compiler and FPC units for the WASI target:

C:\Users\OnlyMe\fpc> make clean all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc

Then, install, using INSTALL_PREFIX to specify a destination folder:

C:\Users\OnlyMe\fpc> make crossinstall OS_TARGET=wasi CPU_TARGET=wasm32 INSTALL_PREFIX=c:\fpcwasm PP=fpc

Add C:\fpcwasm\bin\x86_64-win64 to your PATH to easily run the compiler ppcrosswasm32.exe.

Compilation target: Embedded

Linux and macOS

Build the compiler and FPC units for the 'embedded' target:

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

Then, install, using INSTALL_PREFIX to specify a destination within your home directory:

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

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.

Windows

Make sure the Windows native compiler fpc.exe and the FPC-bundled make.exe are in your PATH. Especially ensure that the FPC make.exe comes first in your PATH; using another make.exe (such as the one installed by Delphi) that happens to be ahead in PATH may not work.

Build the compiler and FPC units for the 'embedded' target:

C:\Users\OnlyMe\fpc> make clean all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc

Then, install, using INSTALL_PREFIX to specify a destination folder:

C:\Users\OnlyMe\fpc> make crossinstall OS_TARGET=embedded CPU_TARGET=wasm32 INSTALL_PREFIX=c:\fpcwasm PP=fpc

Add C:\fpcwasm\bin\x86_64-win64 to your PATH if you have not already done so.

Using the compiler

For Linux and macOS, 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

On Windows, if you have set C:\fpcwasm\bin\x86_64-win64 directory in your PATH, then ppcrosswasm32.exe will be able to find its units.

Using the compiler with 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