Difference between revisions of "WebAssembly/Compiler"
m (→Obtaining the compiler sources: - removed repeated word "now") |
(Add installation instructions for both WASI and embedded targets) |
||
Line 15: | Line 15: | ||
=== Ubuntu 20.04 === | === Ubuntu 20.04 === | ||
− | + | ''wasm-ld'' is part of package ''lld-12''. Install it and set a symlink: | |
− | apt install lld-12 | + | % 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-wasi-wasm-ld |
Note: This assumes you have a $HOME/bin directory and it is in PATH. | Note: This assumes you have a $HOME/bin directory and it is in PATH. | ||
If you need the external assembler, install the package ''llvm-12'' and set a symlink: | If you need the external assembler, install the package ''llvm-12'' and set a symlink: | ||
− | apt install llvm-12 | + | % sudo apt install llvm-12 |
− | ln -sf /usr/lib/llvm-12/bin/llvm-mc ~/bin/wasm32-wasi-llvm-mc | + | % ln -sf /usr/lib/llvm-12/bin/llvm-mc ~/bin/wasm32-wasi-llvm-mc |
=== MacOS === | === MacOS === | ||
Line 34: | Line 34: | ||
Get the sources: | Get the sources: | ||
− | git clone https://gitlab.com/freepascal.org/fpc/source.git fpc | + | % git clone https://gitlab.com/freepascal.org/fpc/source.git fpc |
− | + | Enter the sources directory: | |
− | cd fpc | + | % cd fpc |
== Supported targets == | == Supported targets == | ||
Line 43: | Line 43: | ||
=== WASI - The WebAssembly System Interface === | === WASI - The WebAssembly System Interface === | ||
− | If you are new to building the | + | If you are new to building the compiler, see [[Installing the Free Pascal Compiler]] and [[Cross compiling]]. |
[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 or in the browser. See the WASI website for more information. | [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 or in the browser. See the WASI website for more information. | ||
− | To build the compiler and | + | To build the compiler and FPC units for the WASI target: |
− | make all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc | + | % make all OS_TARGET=wasi CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc |
− | + | On Ubuntu 20.04, 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 | ||
+ | |||
+ | 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. | ||
The following units have been ported for the WASI target: | The following units have been ported for the WASI target: | ||
Line 81: | Line 87: | ||
The [[TARGET_Embedded|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. | The [[TARGET_Embedded|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. | ||
− | make all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc | + | % make all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc |
+ | |||
+ | On Ubuntu 20.04, 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 | ||
+ | |||
+ | 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 | ||
+ | |||
+ | For the embedded target, you also need to link ''wasm32-embedded-wasm-ld'' to ''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. | ||
=== Using the compiler === | === 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; add these lines: | |
+ | <pre> | ||
+ | #ifdef cpuwasm32 | ||
+ | -Fu/home/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/* | ||
+ | -Fu/home/yourusername/fpcwasm/lib/fpc/$fpcversion/units/$fpctarget/rtl | ||
+ | #endif | ||
+ | </pre> | ||
− | If your fpc.cfg has | + | By default $HOME/.fpc.cfg (or /etc/fpc.cfg if that's what you use) contains a ''-XP$FPCTARGET-'' flag, so FPC searches for ''wasm32-wasi-wasm-ld'' (for the WASI OS target) or ''wasm32-embedded-wasm-ld'' (for the embedded target). If you want to search for ''wasm-ld'' instead adapt your fpc.cfg as follows: If your fpc.cfg has |
<pre> | <pre> | ||
#IFDEF FPC_CROSSCOMPILING | #IFDEF FPC_CROSSCOMPILING | ||
Line 96: | Line 119: | ||
</pre> | </pre> | ||
− | + | Then, insert '''#IFNDEF CPUWASM32''' : | |
<pre> | <pre> | ||
#IFDEF FPC_CROSSCOMPILING | #IFDEF FPC_CROSSCOMPILING | ||
Line 107: | Line 130: | ||
</pre> | </pre> | ||
− | Otherwise, you have to | + | Otherwise, you have to symlink ''wasm32-wasi-wasm-ld'' and/or ''wasm32-embedded-wasm-ld'' to ''wasm-ld''; and also ''wasm32-wasi-llvm-mc'' to ''llvm-mc'' if you are using the LLVM assembler. |
=== Lazarus === | === Lazarus === |
Revision as of 07:11, 28 March 2022
Instructions
Prerequisites
The wasm-ld linker. This the linker from the LLVM project. The external assembler llvm-mc is optional, since commit bc76487b878e59133ce3c2cc19ebb13f9a9826ea, in which, the internal assembler and object writer was enabled.
LLVM 11.0 and 12.0.1 are known to work.
LLVM 13.0.0 has a known bug when using the FPC external assembler: [1]
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 20.04
wasm-ld is part of package lld-12. Install it and set a symlink:
% sudo apt install lld-12 % ln -sf /usr/lib/llvm-12/bin/wasm-ld ~/bin/wasm32-wasi-wasm-ld
Note: This assumes you have a $HOME/bin directory and it is in PATH.
If you need the external assembler, install the package llvm-12 and set a symlink:
% sudo apt install llvm-12 % ln -sf /usr/lib/llvm-12/bin/llvm-mc ~/bin/wasm32-wasi-llvm-mc
MacOS
Initial tests on MacOS used llvm-11 installed with MacPorts (https://www.macports.org) and according symlinks in /opt/local/bin (wasm32-wasi-llvm-mc -> llvm-mc-mp-11 and wasm32-embedded-llvm-mc -> llvm-mc-mp-11).
Obtaining the compiler sources
The WebAssembly target was merged into FPC SVN trunk in r48955 on 2021-03-14. Since then, Free Pascal has moved to GitLab, so now it's included in the git 'main' branch.
Get the sources:
% git clone https://gitlab.com/freepascal.org/fpc/source.git fpc
Enter the sources directory:
% cd fpc
Supported targets
WASI - The WebAssembly System Interface
If you are new to building the compiler, see Installing the Free Pascal Compiler and Cross compiling.
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.
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 20.04, 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
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.
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 wasmtime version 0.23.0 or in the browser by opening:
https://webassembly.sh/
and drag and dropping the .wasm binary directly into the browser window.
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.
% make all OS_TARGET=embedded CPU_TARGET=wasm32 BINUTILSPREFIX= OPT="-O-" PP=fpc
On Ubuntu 20.04, 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
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
For the embedded target, you also need to link wasm32-embedded-wasm-ld to 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.
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; 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
By default $HOME/.fpc.cfg (or /etc/fpc.cfg if that's what you use) contains a -XP$FPCTARGET- flag, so FPC searches for wasm32-wasi-wasm-ld (for the WASI OS target) or wasm32-embedded-wasm-ld (for the embedded target). If you want to search for wasm-ld instead adapt your fpc.cfg as follows: If your fpc.cfg has
#IFDEF FPC_CROSSCOMPILING #IFDEF NEEDCROSSBINUTILS -XP$FPCTARGET- #ENDIF #ENDIF
Then, insert #IFNDEF CPUWASM32 :
#IFDEF FPC_CROSSCOMPILING #IFDEF NEEDCROSSBINUTILS #ifndef cpuwasm32 -XP$FPCTARGET- #endif #ENDIF #ENDIF
Otherwise, you have to symlink wasm32-wasi-wasm-ld and/or wasm32-embedded-wasm-ld to wasm-ld; and also wasm32-wasi-llvm-mc to llvm-mc if you are using the LLVM assembler.
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)