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, iOS, 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++20 toolchain (clang, gcc, or MSVC)
- GNU flex
- GNU bison
- node.js and npm (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-depsto updatethird_partydependencies -
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_BUILD_LLVM_DYLIB=On -DLLVM_DYLIB_COMPONENTS=all -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.batto updatethird_partydependencies -
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-depsto updatethird_partydependencies -
Install Java 17 or later.
-
Install the Android SDK command line tools, and ensure
ANDROID_SDK_ROOTis set. -
Install all required Android SDK components:
$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --install 'platforms;android-26' 'ndk;26.3.11579264' 'build-tools;34.0.0' platform-tools
or on Windows:
%ANDROID_SDK_ROOT%\cmdline-tools\latest\bin\sdkmanager --install platforms;android-26 ndk;26.3.11579264 build-tools;34.0.0 platform-tools
-
Set
ANDROID_NDK_ROOTto$ANDROID_SDK_ROOT/ndk/26.3.11579264. -
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
-
Run
tools/git-sync-depsto updatethird_partydependencies -
Install the appropriate SDK for iOS development.
-
Sign into a developer account at https://developer.apple.com.
-
Set a TEAM_IDENTIFIER environment varaible to your developer account's 10-character team ID.
-
Generate a Development certificate, download it to your Mac, and add it to your Keychain.
-
Set a CODESIGN_IDENTITY environment variable to the 10-character identifier of your certificate.
-
Register your iOS development Device at https://developer.apple.com/account/resources/devices/add.
-
Generate an App ID for the samples, with Bundle ID
org.toucanlang.sample.*. -
Register an "iOS App Development" provisioning profile at https://developer.apple.com/account/resources/profiles/add with the App ID you generated in the previous step and your MacOS and iOS development devices. Download it to your Mac and set MOBILE_PROVISION_FILE environment variable to its downloaded file path.
-
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-ios
echo is_debug=false > out/Release-ios/args.gn
echo target_os=\"ios\" >> out/Release-ios/args.gn
echo mobile_provision=\"$MOBILE_PROVISION_FILE\" >> out/Release-ios/args.gn
echo codesign_identity=\"$CODESIGN_IDENTITY\" >> out/Release-ios/args.gn
echo team_identifier=\"$TEAM_IDENTIFIER\" >> out/Release-ios/args.gn
gn gen out/Release-ios
ninja -C out/Release-ios
- 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/Release-wasm
echo 'is_debug=false\
target_os="wasm"\
target_cpu="wasm"' > out/Release-wasm/args.gn
gn gen out/Release-wasm
ninja -C out/Release-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/Release-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)
$ANDROID_SDK_ROOT/platform-tools/adb install -r out/Release-android/$SAMPLE.apk
$ANDROID_SDK_ROOT/platform-tools/adb shell am start -a android.intent.action.MAIN -n org.toucanlang.$SAMPLE/android.app.NativeActivity
e.g.,
$ANDROID_SDK_ROOT/platform-tools/adb install -r out/Release-android/springy.apk
$ANDROID_SDK_ROOT/platform-tools/adb shell am start -a android.intent.action.MAIN -n org.toucanlang.springy/android.app.NativeActivity
xcrun devicectl device install app out/Release-ios/${SAMPLE}.ipa --device ${IOS_DEVICE_ID}
xcrun devicectl device process launch --device ${IOS_DEVICE_ID} "org.toucanlang.sample.${SAMPLE}"
e.g.,
xcrun devicectl device install app out/Release-ios/springy.ipa --device ${IOS_DEVICE_ID}
xcrun devicectl device process launch --device ${IOS_DEVICE_ID} "org.toucanlang.sample.springy"
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 desktop platforms.
On Linux and MacOS:
test/test.py >& test/test-expectations.txt
On Windows:
python3 test\test.py > test\test-expectations.txt 2>&1
python3 tools\unixify.py test\test-expectations.txt