This is not an officially supported Google product.
Toucan is an experimental, domain-specific language for accelerated graphical applications. It was designed to answer the following question: "Could a unified programming environment reduce the friction of developing CPU/GPU apps?". Built on WebGPU and featuring unified CPU/GPU SIMD datatypes, syntax and API, it aims for native-level performance with a single, concise source. It currently runs on Windows, MacOS, Linux, Android, and Web.
For further information, see this presentation and this document.
If you simply wish to try some live Toucan demos without building the toolchain, navigate to the Toucan Samples page and follow the instructions.
- Python 3.0
- CMake
- A C++17 toolchain (clang, gcc, or MSVC)
- GNU flex
- GNU bison
- node.js (for the WebAssembly build)
Toucan uses the GN and ninja build systems from the Chromium project. These will be retrieved by the git-sync-deps script.
tj
: the Toucan JIT compiler. Accepts a single Toucan file, performs compilation, semantic analysis, code generation, JITs the result, and runs it with an embedded runtime API. Runs on Windows/D3D11, Mac/Metal (x86) and Linux/Vulkan.tc
: the Toucan static compiler. Performs compilation, semantic analysis and code generation, and produces a native executable. Targets all of the above, plus the Web (via WebAssembly).springy
: a particle-based physics demo, with a 10x10 grid of particlesspringy-compute
: the same particle demo, running in a compute shaderspringy-3d
: a larger, 3D mesh version of "springy"springy-compute-3d
: a compute-based version of "springy-3d"shiny
: a cube-mapped reflective Utah teapot, rendered in a skybox
-
Run
tools/git-sync-deps
to updatethird_party
dependencies -
Build LLVM (Makefiles):
pushd third_party/llvm/llvm
mkdir -p out/Release
cd out/Release
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="lld;clang" -DLLVM_TARGETS_TO_BUILD="host;X86;ARM;AArch64;WebAssembly" -DLLVM_INCLUDE_BENCHMARKS=false -DLLVM_INCLUDE_EXAMPLES=false -DLLVM_INCLUDE_TESTS=false ../..
make
popd
- Build tc, tj and native samples:
mkdir -p out/Release
echo "is_debug=false" > out/Release/args.gn
gn gen out/Release
ninja -C out/Release
-
Run
tools\git-sync-deps.bat
to updatethird_party
dependencies -
Build LLVM (Visual Studio project files):
pushd third_party\llvm\llvm
mkdir out
cd out
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="lld;clang" -DLLVM_TARGETS_TO_BUILD="host;X86;ARM;AArch64;WebAssembly" -DLLVM_INCLUDE_BENCHMARKS=false -DLLVM_INCLUDE_EXAMPLES=false -DLLVM_INCLUDE_TESTS=false ..
cmake --build . --config Release
popd
- Install Bison and Flex:
python3 tools/fetch-win-flex-bison.py
- Build tc, tj and native samples:
mkdir out\Release
echo is_debug=false > out\Release\args.gn
gn gen out\Release
ninja -C out\Release
-
Run
tools/git-sync-deps
to updatethird_party
dependencies -
Install the Android SDK, and ensure ANDROID_SDK_ROOT is set.
-
Install the Android NDK (r26d is known to work), and sure ANDROID_NDK_ROOT is set.
-
Build LLVM (Makefiles):
pushd third_party/llvm/llvm
mkdir -p out/Release
cd out/Release
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="lld;clang" -DLLVM_TARGETS_TO_BUILD="host;X86;ARM;AArch64;WebAssembly" -DLLVM_INCLUDE_BENCHMARKS=false -DLLVM_INCLUDE_EXAMPLES=false -DLLVM_INCLUDE_TESTS=false ../..
make
popd
- Build tc and native samples:
mkdir -p out/Release-android
echo is_debug=false > out/Release-android/args.gn
echo target_os=\"android\" >> out/Release-android/args.gn
echo target_cpu=\"arm64\" >> out/Release-android/args.gn
echo android_ndk_dir=\"$ANDROID_NDK_ROOT\" >> out/Release-android/args.gn
echo android_sdk_dir=\"$ANDROID_SDK_ROOT\" >> out/Release-android/args.gn
gn gen out/Release-android
ninja -C out/Release-android
- Bootstrap emscripten
pushd third_party/emscripten
./bootstrap
popd
- Build binaryen
pushd third_party/binaryen
git submodule init
git submodule update
cmake . && make
popd
- Build WASM targets
mkdir -p out/wasm
echo 'is_debug=false\
target_os="wasm"\
target_cpu="wasm"' > out/wasm/args.gn
gn gen out/wasm
ninja -C out/wasm
out/DIR/tj <filename>
e.g., out/Release/tj samples/springy.t
out/DIR/<filename>
e.g., out/Release/springy
npx http-server out/wasm
- start Chrome with the runtime flag
--enable-features=WebAssemblyExperimentalJSPI
, or enable "Experimental WebAssembly JavaScript Promise Integration (JSPI)" in about:flags - open
http://localhost:8080
- open sample (e.g., springy.html)
adb install -r out/Release-android/$SAMPLE.apk
adb shell am start -a android.intent.action.MAIN -n org.toucanlang.$SAMPLE/android.app.NativeActivity
e.g.,
adb install -r out/Release-android/springy.apk
adb shell am start -a android.intent.action.MAIN -n org.toucanlang.springy/android.app.NativeActivity
There is a primitive test harness in test/test.py, and a set of end-to-end tests. This requires tj, so it is only supported on Windows, Mac and Linux. Run it as follows:
test/test.py >& test/test-expectations.txt