Clang-Supported Languages
Because the IC supports dapps compiled to standard WebAssembly modules, you can use standard compilers and toolchains to build applications in languages such as C, C++, Objective-C, and Objective-C++ programming languages and the Clang compiler.
Using C
To illustrate how to migrate dapps written in C to run on the IC, let’s look at the simple reverse.c program in the examples repository. The reverse.c program contains one function—named go—that reverses a string in place.
Set up the development environment
To compile the reverse.c program into WebAssembly, you need to have the clang compiler and standard libraries installed. You can check whether you have clang installed on your local computer by running the following command:
clang --version
If clang is installed, the command displays information similar to the following:
clang version 10.0.0
Target: x86_64-apple-darwin19.5.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
If the command doesn’t return version information, install clang before continuing. The steps to install clang vary depending on the operating system you are using. On Debian Linux, for example, run the following command:
sudo apt-get install clang lld gcc-multilib
On macOS, you can install clang by installing the Developer Command-Line Tools or by installing LLVM using Homebrew. For example, if clang is not installed, run the following command:
brew install llvm
Compile the program into WebAssembly
You can compile a C program to run as a WebAssembly module by first compiling using clang, then linking using wasm-ld. Depending on the operating system and version of clang you are using, you might use a different version of the WebAssembly linker, such as wasm-ld on macOS or wasm-ld-8 on Debian.
To compile to WebAssembly on macOS:
Compile the program by running the following clang command:
clang --target=wasm32 -c -O3 reverse.cRun the linker to create the WebAssembly module by running the following
wasm-ldcommand:wasm-ld --no-entry --export-dynamic --allow-undefined reverse.o -o reverse.wasm
Create a minimal configuration file
Next, you need to prepare a simple configuration file that identifies the reverse dapp binary as a package that can be installed on the IC and a build directory so that you can use the dfx command-line interface to install and run the package as a canister.
To prepare a configuration file and build directory:
Create a
dfx.jsonfile with a canisters key by running the following command:echo '{"canisters":{"reverse":{"main":"reverse"}}}' > dfx.jsonCreate a
builddirectory for the dapp by running the following command:mkdir buildCreate a
reversedirectory for the dapp by running the following command:mkdir build/reverseCopy the WebAssembly modules to the new
build/reversedirectory by running the following command:cp reverse.wasm build/reverse/
Create a minimal interface description file
In a standard development workflow, running the dfx build command creates several files in the canisters output directory, including one or more Candid interface description (.did) files that handle type matching for the data types associated with a program’s functions.
For details about the syntax to use for different data types, see the Candid Guide and Candid specification.
To create a Candid interface description file for this program:
Open a terminal in the
builddirectory you created for thereverse.cprogram sourceCreate a new text file named
reverse.did.Add a description of the
gofunction.For example:
service : {
"go": (text) -> (text);
}Save your changes and close the file to continue.
Deploy and test the dapp
Before you can deploy and test your dapp, you need to do the following:
Connect to either the local canister execution environment, or to the IC blockchain mainnet.
Register a network-specific identifier for the application.
To deploy and test the dapp locally:
Open a new terminal window or tab on your local computer.
For example, if running Terminal on macOS,click Shell, then select New Tab to open a new terminal in your current working directory.
Start the local canister execution environment in your second terminal by running the following command:
dfx startRegister a unique canister identifier for the
reverseapplication by running the following command:dfx canister create --allDeploy the default dapp on the local canister execution environment by running the following command:
dfx canister install --allCall the
gofunction in the dapp by running the following command:dfx canister call reverse go reward
("drawer")
You can find additional examples of C dapps in the examples repository.