Counter-Strike 2 made me learn how to setup Flutter with WSL 2
What does Valve’s latest game have to do with Flutter, WSL 2, and Linux on your PC?
About 2 years ago I started using Linux as my default system for development purposes. As a casual Counter-Strike player, I installed it on my Linux environment. No big deal. Then Counter Strike 2 Limited Test came out of the shadows and I was thrilled to test it on my Ubuntu. Until I read the F.A.Q.
Can I participate in the Counter-Strike 2 Limited Test on Linux or macOS?
No. The Counter-Strike 2 Limited Test is only available on Windows.
That was a hard one to take. I thought: should I go dual boot all the way to just play one game? Not me, sir. So I formatted everything and installed Windows 11. Here I am testing my super-limited CS2, happy as a kid on Christmas morning.
Then the reality stroke: I need to set up my Flutter environment on Windows 11. You know the drill: install git, VS Code, Android Studio, configure ssh, yada, yada, yada… There is nothing wrong with it. Windows offers good support for development tools these days. But it's not Linux… yet.
So I decided to look for solutions, and that’s when I found a very nice article that goes through all the headaches to configure WSL 2 in Windows 10.
All good and simple, right? Not for me. I struggled a bit and had to do it all over again a few times. They say practice makes perfect, right? Then I came across an article from the other side of the world — in Japanese, can you believe this? — that guided me in a different way from the first one but to achieve basically the same results — thank you Google Translate by the way.
So I decided to make my own article to bring the previous pieces of knowledge together to share with anyone who has struggled — or is about to. Let’s get started right away, shall we? This is quite a tedious, step-by-step tutorial, so I had to summarize it:
- Preparation of Ubuntu environment at WSL 2
- Java SDK and Android SDK installation
- Building a Flutter development environment
- VS Code settings
- Create a Flutter demo project
- Running a project on a physical Android Device
Preparation of Ubuntu environment at WSL 2
Download and import Ubuntu 22.04
Decide which path and name to install Ubuntu first.
The environmental name is here flutter-env
. The destination will be inside wsl
in the user's home folder to keep things simple and easy to find.
C:\Users\your-user-folder\wsl
Download the WSL image of your choice from the Ubuntu release page. I used Ubuntu 22.04.2 LTS (Jammy Jellyfish).
Note: in this tutorial, I’m using > for powershell commands on Windows, and $ or # for bash on WSL. Remember this!
Use wsl --import
command on the Windows terminal to point to the folder created earlier. Change path-to-user-folder
, path-to-download-folder
and ubuntu-image-downloaded.tar.gz
accordingly to your case.
> wsl --import flutter-env path-to-user-folder\wsl\flutter-env path-to-download-folder\ubuntu-downloaded-image.tar.gz --version 2
The command above creates a new instance of Linux inside Windows, also known as WSL (Windows Subsystem for Linux). To check it out, use the command wsl -l -v
. The output should be something like the following:
> wsl -l -v
NAME STATE VERSION
* flutter-env Stopped 2
The installation folder should contain ext4.vhdx
file. That’s it for now. You completed the first step! Let's set up our Ubuntu.
Ubuntu initial settings
Execute the following command to start your WSL instance.
> wsl -d flutter-env
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.10.16.3-microsoft-standard-WSL2 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This message is shown once a day. To disable it please create the
/root/.hushlogin file.
root@your-machine-name:/mnt/c/Users/your-user-name/wsl#
At this point the login user isroot
, so add your preferred user. In my case I addeddev
, it's up to you to define your own username. Then set up a password and lastly set sudo privileges to the user.
# useradd -m -s $(which bash) dev
# passwd dev
New password:
Retype new password:
passwd: password updated successfully
# usermod -G sudo dev
Access /etc/wsl.conf
to edit WSL settings. If no file is found, a new one would be created.
# sudo nano /etc/wsl.conf
The first instruction sets the default user and the second ignores the Windows path in the WSL instance.
[user]
default=dev
[interop]
appendWindowsPath = false
The setting in root is complete. Exit the wsl instance and restart it.
# exit
> wsl -t flutter-env
> wsl -d flutter-env
If you see the name of the created user, everything is working fine.
dev@your-machine-name:~$
Continue to set the home directory as default when opening the terminal and set PATH when logging in. To set up VS Code in your PATH, make sure you have it installed in Windows first. Execute the source
command to update the PATH variable in your working session.
$ echo cd >> ~/.bashrc
$ echo export PATH=\$PATH:/mnt/c/WINDOWS/ >> ~/.bashrc
$ echo export PATH=\$PATH:\"/mnt/c/Users/your-user-name/AppData/Local/Programs/Microsoft VS Code/bin\" >> ~/.bashrc
$ source ~/.bashrc
Note: the
cd
command is executed everytime the terminal is open. This can be a problem in the future when you open your Flutter project using thecode .
command because it will not open VS Code terminal in that folder automatically, so you have to execute the commandcd my-flutter-project-path
to execute Flutter or Dart commands. It’s up to you that decision to maintain or remove thecd
command from.bashrc
file.
Once set, update and install the unzip
package. Once the update, upgrade, and installation are complete, log out from WSL.
$ sudo apt update -q; sudo apt upgrade -yq
$ sudo apt install -y unzip
$ exit
If you make it this far, you should export the image to save the snapshot of this initial setup. This way you can use it in the future and save some quality time. Change the export path to your preferred location. I saved it in the same folder as my flutter-env
root installation.
> wsl -t flutter-env
> wsl -l -v
> wsl --export flutter-env path-to-user-folder\wsl\flutter-env.tar
At this point, it was about ~1 to 1.5GB. If you ever want to restore it in the future, specify this tar file and import it as at the beginning of this process, and that is it. Well, a new step is done! Congratulations again, my friend. Let’s install the Java and Android SDK.
Java SDK and Android SDK installation
Java SDK installation
Install Java SDK with the following commands on WSL. I don’t think there is any particular problem. If so, Google it and move on.
$ sudo apt update && sudo apt install default-jdk -y
$ export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
$ ll $JAVA_HOME
$ echo export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 >> ~/.bashrc
$ echo export PATH=\$PATH:\$JAVA_HOME/bin >> ~/.bashrc
$ source ~/.bashrc
$ echo $JAVA_HOME
$ echo $PATH
Android SDK Installation
To install Android SDK, first, go to the official page and find “Command line tools only”. Click the Linux version of the link to get the SDK zip URL. Copy that link to use in a bit.
In my case, the link was https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip
Once you have the link, run the command and download the Android SDK as below. Replace the part of copied-link-from-previous-step
and run it.
$ mkdir -p ~/Android/SDK/cmdline-tools
$ wget copied-link-from-previous-step -O latest.zip
$ unzip latest.zip
$ mv cmdline-tools ~/Android/SDK/cmdline-tools/tools
$ rm -rf latest.zip
$ echo export ANDROID_HOME=\$HOME/Android/SDK >> ~/.bashrc
$ echo export PATH=\$PATH:\$ANDROID_HOME/cmdline-tools/tools/bin >> ~/.bashrc
$ source ~/.bashrc
$ sdkmanager
[=======================================] 100% Computing updates...
Execute the following commands to install all the tools needed in Command Line Tools, like system images, Android Debug Bridge (adb), and other things.
$ sdkmanager --install "system-images;android-33;google_apis;x86_64" "platform-tools" "platforms;android-33" "build-tools;33.0.2" "cmdline-tools;latest"
$ echo export PATH=\$PATH:\$ANDROID_HOME/platform-tools >> ~/.bashrc
$ source ~/.bashrc
$ adb --version
Android Debug Bridge version 1.0.41
Version 34.0.3-10161052
Installed as /home/your-user-name/Android/SDK/platform-tools/adb
Running on Linux 5.10.16.3-microsoft-standard-WSL2 (x86_64)
Please confirm and agree to the Android SDK license with the command below.
$ sdkmanager --licenses
Yet another step is finished. We are almost done. Let’s install and set up our sweet Flutter environment!
Building a Flutter development environment
Install Flutter
It’s time to finally install Flutter on our Linux machine! There are a bunch of ways to do that (download the zip file, snap, git…). I choose git
because looks easier and has clear steps. Execute the command below to download the latest stable version from Flutter's official Github repository:
$ git clone https://github.com/flutter/flutter.git -b stable
The next step is to export the FLUTTER_ROOT environment variable:
$ echo export FLUTTER_ROOT=\$HOME/flutter >> ~/.bashrc
$ echo export PATH=\$PATH:\$FLUTTER_ROOT/bin >> ~/.bashrc
$ source ~/.bashrc
$ flutter --version
Downloading Linux x64 Dart SDK from Flutter engine 90fa3ae28fe6ddaee1af2c120f01e50201c1401b...
...
Flutter 3.10.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 9cd3d0d9ff (8 days ago) • 2023-05-23 20:57:28 -0700
Engine • revision 90fa3ae28f
Tools • Dart 3.0.2 • DevTools 2.23.1
Installing tools for Linux apps (optional)
To check the installation status, run flutter doctor
command.
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.2, on Ubuntu 22.04.2 LTS 5.10.16.3-microsoft-standard-WSL2, locale C.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✗] Linux toolchain - develop for Linux desktop
✗ clang++ is required for Linux development.
It is likely available from your distribution (e.g.: apt install clang), or can be downloaded from
https://releases.llvm.org/
✗ CMake is required for Linux development.
It is likely available from your distribution (e.g.: apt install cmake), or can be downloaded from
https://cmake.org/download/
✗ ninja is required for Linux development.
It is likely available from your distribution (e.g.: apt install ninja-build), or can be downloaded from
https://github.com/ninja-build/ninja/releases
✗ pkg-config is required for Linux development.
It is likely available from your distribution (e.g.: apt install pkg-config), or can be downloaded from
https://www.freedesktop.org/wiki/Software/pkg-config/
[!] Android Studio (not installed)
[✓] Connected device (1 available)
[✓] Network resources
Do you see that Linux toolchain — develop for Linux desktop
uncheck? Optionally, you can download Linux tools in order to develop Linux applications. Just execute the following command:
$ sudo apt install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
Run flutter doctor
again:
kaio@b2d:~$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.2, on Ubuntu 22.04.2 LTS 5.10.16.3-microsoft-standard-WSL2, locale C.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Linux toolchain - develop for Linux desktop
[!] Android Studio (not installed)
[✓] Connected device (1 available)
[✓] Network resources
Android Studio is not necessary at this time because we are using the command line tools for Android SDK. As for Chrome, we can set another browser inside VS Code later or install Chrome on Windows so it can recognize it.
That’s it for now. Flutter and Dart's configs are done, my good developer friend. Can you feel the air getting harder to breathe? Yeah, we are almost at the top!
VS Code settings
If you already have VS Code installed on Windows and set the environment in the early stages, you can execute the code .
on the home directory.
$ code .
Installing VS Code Server for x64 (b3e4e68a0bc097f0ae7907b217c1119af9e03435)
Downloading: 100%
Unpacking: 100%
Unpacked 1759 files and folders to /home/your-user-name/.vscode-server/bin/b3e4e68a0bc097f0ae7907b217c1119af9e03435.
You should see the information below on VS Code status bar. If not, it will suggest you download WSL extensions and whatnot.
You can install Dart and Flutter extensions in this environment or in the Windows environment. Either way, it’s necessary to integrate Dart and Flutter with VS Code.
Here we are. One more step on the pocket. There are two more to go. Keep it up!
Create a Flutter demo project
Go to your home and create a folder where you will create some Flutter Projects. In my case, I called projects
:
$ mkdir projects && cd projects
$ flutter create -e my_app
The -e
flag indicates an empty project that builds a “Hello World” centered text — the default is the counter app with comments.
Now comes the best and final part. Running the project on a physical device!
Running a project on a physical Android Device
Since you are running your Linux in a virtual environment, you must do some operations both on Windows and on the WSL instance.
- On Windows, make sure to download and install Android SDK, Command Line Tools, set environment variables, etc… The same way we did in the previous steps on WSL.
- Remember to turn on debug mode on your Android device.
Then check if you have any devices connected. If not, that’s probably because debug mode is off. If you execute the command below and the message to authorize access on the device is shown, but it took too long to be accepted, the list of devices might show as unauthorized
. Just execute it again so it shows as device
.
> adb devices
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
ZF5232PKQV unauthorized
> adb devices
List of devices attached
ZF5232PKQV device
Update the default connection port to 5555
and connect to the physical device’s IP address.
> adb tcpip 5555
restarting in TCP mode port: 5555
> adb connect 1.2.3.3:5555
On WSL, execute adb devices
the command to check if the connection is established.
$ adb devices
List of devices attached
1.2.3.4:5555 device
To make sure everything is working, execute flutter devices
command.
$ flutter devices
2 connected devices:
motorola one macro (mobile) • 1.2.3.4:5555 • android-arm64 • Android 10 (API 29)
Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.2 LTS 5.10.16.3-microsoft-standard-WSL2
On WSL, go to the project’s folder and open it with VS Code using code .
command. Wait for the device to be connected, and then execute the project (run/debug).
That’s it. Your Flutter / WSL 2 Environment is fully configured! Hard work, congratulations 👏🥳