Samstag, 29. Mai 2021

Flutter with Vim on Debian

 Let there be Flutter!

I thought it would be as easy as it was getting Dart up and running…

Getting Dart running on Debian was easy. Their documentation on how to install is short. Basically it is:

  • Add the signature key for the apt repository
  • Add the repository
  • Use apt to install dart
  • Modify your PATH to have access to dart binaries
  • Maybe install some global packages like devtools, stagehand, webdev
  • And adding another path to your PATH

As Flutter comes from the same direction, I thought, that installing it would be as easy as that.

But no, it isn't.

 Yes, it is not very hard. But getting it going completely with the Android emulator, and all from the command line, was not.

First, installing Flutter itself does not have an apt repository. The installation instructions give you the option for either a snap package, or a compressed collection of files, that you just decompress and adjust your PATH towards it.

To get the most learning out of it (by triggering more problems, it seems), I had chosen the snap way. 

  • $ aptitude install snapd         
  • $ snap install flutter --classic 
  • adjust PATH to include the snap-binaries: PATH="$PATH":"/snap/bin"

They recommend you to check flutter doctor for checking if all is running well. In my case it said that the Android toolchain and Android Studio were missing.

[!] Android toolchain - develop for Android devices
    • Android SDK at /some/where/AndroidSDK/
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

    ✗ Android SDK file not found: adb.
    • Try re-installing or updating your Android SDK,
      visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions.

Checking the Debian packages, there is a android-sdk available, but just for SDK platform 23, which seems to be Android 6 / Marschmallow. Currently Android is already at Version 11. Therefore I had chosen to install a newer version, which can be gotten via the androidsdk, which can be installed via snap:

  • $ snap install androidsdk 

It has a list of available packages, androidsdk --list, where it is a little bit confusing on what to choose from, I think.

Fiddling around, I found the following should be there:

  • $ androidsdk platform-tools "build-tools;30.0.3" "platforms;android-30" "cmdline-tools;latest" "system-images;android-30;google_apis_playstore;x86_64"

If the doctor doesn't find it, e.g. with the message No valid Android SDK platforms found, the path might not be right. Use the suggested $ flutter config --android-sdk to point to the path, where the SDK is installed. In my case I have it set to:

  • $ flutter config --android-sdk ~/AndroidSDK

Now it probably warns you about license status: Android license status unknown.

Use

  • $ androidsdk --licenses
  • $ flutter doctor --android-licenses

to accept the licenses. If you now get the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: javax.xml.bind.annotation.XmlSchema

Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema

you are probably missing the cmdline-tools, of course. Make sure that you have used androidsdk to install this too.

Now we set up the emulator by calling:

  • $ flutter emulators --create

If it complains with the following message, then you didn't install a suitable system image with androidsdk:

No suitable Android AVD system images are available. You may need to install these using sdkmanager, for example:
 sdkmanager "system-images;android-27;google_apis_playstore;x86"

To get your virtual Android up and running, run the following command:

  • $ flutter emulators --launch flutter_emulator

In my case it didn't directly work. It complained about missing KVM support. 

handleCpuAcceleration: feature check for hvf

With the cpu-checker package from apt, the command kvm-ok returned the information, that KVM is theoretically possible on my machine, but it currently is disabled. Go to the BIOS and enable it. In my BIOS it was not named KVM or VT or AMD-V or VMX or something like that, but it is SVM.

Coming back into the system, flutter didn't work right anymore, giving me the message:

snap-confine has elevated permissions and is not confined but should be. Refusing to continue to avoid permission escalation attacks

cannot change profile for the next exec call: No such file or directory

Apparmor was blocking access now that the hardware accelerated virtualization was enabled. Digging around the following commands helped:

  • $ apparmor_parser -r /etc/apparmor.d/*snap-confine*
  • $ apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap-confine*
  • $ apparmor_parser -r /var/lib/snapd/apparmor/profiles/*
  • $ systemctl enable --now apparmor.service

After that, the emulator would start and work.

 

Basic set up done.


The next step was to create a simple Flutter project and get that running. Therefore I used $ flutter create myFirstProject . It creates a basic project with all needed files. Trying to $ flutter run it directly failed in my case.

 With SDKMAN! I already had Java and Gradle installed, which are needed to create the Android APK. I wanted new and current versions, so I had updated older versions (Java 11, Gradle 6.3) to Java 16. With the error message:

BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 60

my first instinct was to update also Gradle as that old version probably did not support the new Java version. But it failed again. Looking more closely and with the -v verbose option on, I saw, that the building didn't use my Gradle, but hat a version on its own, which is version 6.7, which doesn't support Java 16...

The solution in this case was to use sdkman to downgrade Java. Most options were either version 16 or 11, so I chose version 11.

Finally, a working Flutter set up, that creates, compiles, runs.

(Writing this post I came across the problem of needing to remove the already create  flutter_emulator emulator, which Flutter created last time. It just has the option to create, but not to remove. For that you need to use the avdmanager like this:

  • $ ~/AndroidSDK/cmdline-tools/latest/bin/avdmanager delete avd --name flutter_emulator

)

 

On to using Vim for the development.

Simple Dart support comes with the plugin dart-lang/dart-vim-plugin.

More fancy features come with using the language server protocol. I use prabirshrestha/vim-lsp, which I already had a little post on how to set it up.

mattn/vim-lsp-settings provides an installer for setting up the
analysis-server-dart-snapshot. As I already have Dart set up as a system package, which gets updated that way, I also want to directly use that given analysis server, which can simply be defined with this line in the .vimrc:

let g:lsp_settings = {
    \ 'analysis-server-dart-snapshot': {
    \     'cmd': [
    \         '/usr/lib/dart/bin/dart',
    \         '/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot',
    \         '--lsp'
    \     ]
    \ }
\ }

Then there is Flutter. For it there is another Vim plugin: thosakwe/vim-flutter

For debugging, the puremourning/vimspector plugin for Vim has already information on how to get it running with Dart & Flutter. But that is just to tiny to get instantly going.

What to do:

  • Install the vimspector vim-plugin by e.g. adding it to your list of plugins in your .vimrc
  • Clone Dart-Code/Dart-Code with git in a different directory and build it

In my case, I already had npm installed. But you might need it:

  • $ aptitude install npm

 

  • $ git clone https://github.com/Dart-Code/Dart-Code
  • $ cd Dart-Code

Better check out a stable version then the current master

  • $ git checkout v3.22.0

You might need to install webpack, as without the build will probably fail

  • $ npm install webpack

And then build that project, and hope, that it works without problems

  • $ npm run build 

(If something fails you might need to clean that directory, e.g. with $ git clean -dxf)

After that, there should be the needed file out/dist/debug.js be created.


Now we need to create two files, one defines general "gadgets" for vimspector, and the other defines the needed variables in your project. 

The gadget-file should go either 

~/.vim/plugged/vimspector/gadgets/linux/.gadgets.json

or

~/.vim/plugged/vimspector/gadgets/linux/.gadgets.d/dart-flutter-gadgets.json

(I found other possible locations or names, which didn't work for me.)

In mine there is currently the following inside:

{
    "adapters": {
        "dart-test-code": {
            "command": [
                "node",
                "${root}/out/dist/debug.js",
                "dart_test"
            ],
            "type": "dart_test",
            "variables": {
                "root": "/home/myself/projects/dart_projects/Dart-Code"
            }
        },
        "dart-code": {
            "command": [
                "node",
                "${root}/out/dist/debug.js",
                "dart"
            ],
            "type": "dart",
            "variables": {
                "root": "/home/myself/projects/dart_projects/Dart-Code"
            }
        },
        "flutter-test-code": {
            "command": [
                "node",
                "${root}/out/dist/debug.js",
                "flutter_test"
            ],
            "type": "flutter_test",
            "variables": {
                "root": "/home/myself/projects/dart_projects/Dart-Code"
            }
        },
        "flutter-code": {
            "command": [
                "node",
                "${root}/out/dist/debug.js",
                "flutter"
            ],
            "type": "flutter",
            "variables": {
                "root": "/home/myself/projects/dart_projects/Dart-Code"
            }
        },
        "multi-session": {
            "host": "${host}",
            "port": "${port}"
        }
    }
}

It defines 4 different types, which then can be used in all projects.

In the project folder, there should be the .vimspector.json

And that one contains e.g.:

{
    "configurations": {
        "launch": {
            "adapter": "flutter-code",
            "configuration": {
                "request": "launch",
                "type": "flutter",
                "flutterSdkPath": "/snap",
                "dartSdkPath": "/usr/lib/dart/bin",
                "program": "${workspaceRoot}/lib/main.dart",
                "args": ["-d", "emulator-5554"],
                "cwd": "${workspaceRoot}"
            }
        }
    }
}

It tells Vimspector to use the previously defined flutter-gadget and which the starting file would be. In my case I also needed to add the "args" entry. Without it, starting debugging, it would error out as it would have multiple options for running the program on, as it would see: an emulator, a real device, and a web browser.

Inside vim, inside the main.dart file, running the debugger should work:

:call vimspector#Launch()

You should start the emulator first, if you want to use that:

:FlutterEmulators --launch flutter_emulator

 
 

Somehow my normal bindings for Vimspector (F5, F8) don't work. Probably because Vimspector doesn't directly recognize the dart files, and therefore doesn't set up the bindings.

For now I am okay using :call vimspector#Something

It works... for now :D 

Keine Kommentare:

Kommentar veröffentlichen

[Review/Critic] UDock X - 13,3" LapDock

The UDock X - 13.3" LapDock is a combination of touch display, keyboard, touch-pad and battery. It can be used as an extension of vari...