Closed Dieterbe closed 1 day ago
also shows a logfile which shows that actually, it can find dart
The message says that it can't find Dart in the Flutter SDK. For Flutter, we will only use a Dart SDK that is bundled with Flutter.
The issue seems to be that we're not detecting the correct location of a Flutter SDK:
[4:07:06 PM] [General] [Info] Found at:
[4:07:06 PM] [General] [Info] /usr/bin
[4:07:06 PM] [General] [Info] /sbin
[4:07:06 PM] [General] [Info] Following symlink: /sbin/flutter -> /usr/bin/flutter
[4:07:06 PM] [General] [Info] Candidate paths to be post-filtered:
[4:07:06 PM] [General] [Info] /usr/bin -> /usr
[4:07:06 PM] [General] [Info] /sbin -> /usr
[4:07:06 PM] [General] [Info] Found at /usr/bin -> /usr
[4:07:06 PM] [General] [Info] Returning SDK path /usr for flutter
[4:07:06 PM] [General] [Info] Flutter is not initialized, running 'flutter doctor' to force...
We found a Flutter binary at /usr/bin/flutter
and because it ends with bin/flutter
, we've concluded that /usr
is the location of the Flutter SDK which is not correct, and therefore we've looked for a Dart SDK at /usb/bin/cache/dart-sdk/
.
If we had discounted /usr
as a Flutter SDK, probably you'd get a better error that we failed to find the Flutter SDK and you'd be offered to manually select it.
Can you confirm:
flutter
binary, but the entire git repo)/usb/bin/flutter
? Is it a symlink or a binary? If it's a binary, where did it come from/what is it? (the standard flutter
binary needs to live inside its Git repository because it will read other files alongside it).Thanks!
Hello @DanTup thanks for your response.
i have a full clone of ssh://git@github.com/flutter/flutter.git
in /opt/flutter . (as setup by the flutter-bin AUR package on arch linux). this is my flutter SDK indeed. i don't think i have other flutter sdk's elsewhere, though i did install 'melos' recently but i don't think it's related.
for the 2nd question. it seems it is a wrapper script that was installed by the same flutter-bin package.
[root@xps17 ~]# cat /usr/bin/flutter
#!/usr/bin/env bash
source /usr/bin/flutter_init
if ! grep -q '/usr/bin' <<< "$(which flutter)"; then
exec flutter "$@"
fi
[root@xps17 ~]# pacman -Qo /usr/bin/flutter
/usr/bin/flutter is owned by flutter-bin 3.22.2-1
[root@xps17 ~]#
for completeness, i can add:
which flutter
resolves to '/usr/bin/flutter'Great, thanks for the info. I think I can fix this by expanding the check for what we consider a Flutter SDK:
Right now we assume if we find a flutter
executable that's inside a bin
sub-folder, it's an SDK, but that's too greedy here. We could also check for some other files we know a Flutter SDK would have (bin/internal/
or packages/flutter
).
I'll work on a fix and push it to the pre-release channel next week for you to try out. Thanks!
Oh btw, I'm assuming that you can run /opt/flutter/bin/flutter
with no problem (eg. /opt/flutter/bin/flutter doctor
and /opt/flutter/bin/flutter run
)? Since once I've fixed this, that's what we'll end up using from the extension. We have to track a full SDK because we use other tools from inside it, so we will always run Flutter directly from the SDK folder and not some wrapper script that happens to exist on PATH
.
Hi @DanTup thank you for the followup. I don't quite fully understand your proposed solution, but it sounds like it will make it work, so i'm all for it.
yes, i can run a project using /opt/flutter/bin/flutter run
.
as for doctor, it now shows a (minor?) warning:
~ ❯❯❯ /opt/flutter/bin/flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[!] Flutter (Channel stable, 3.22.2, on Arch Linux 6.9.7-arch1-1, locale en_US.utf-8)
! Warning: `flutter` on your path resolves to /usr/bin/flutter, which is not inside your current Flutter SDK checkout at /opt/flutter. Consider adding /opt/flutter/bin to the front of your path.
! Warning: `dart` on your path resolves to /usr/bin/dart, which is not inside your current Flutter SDK checkout at /opt/flutter. Consider adding /opt/flutter/bin to the front of your path.
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2022.3)
[✓] Connected device (2 available)
[✓] Network resources
! Doctor found issues in 1 category.
BTW, in case you need my PATH:
~ ❯❯❯ echo $PATH
/home/dieter/bin:/usr/local/bin:/usr/local/sbin:/home/dieter/scripts:/home/dieter/code/vcsh:/home/dieter/code/snip:/home/dieter/code/dmenu-solarized:/home/dieter/go/bin:/home/dieter/code/git-scripts:/home/dieter/code/codemod/src:/home/dieter/code/dclean:/home/dieter/code/ddm:/home/dieter/code/svn-scripts:/usr/share/bcc/tools:/home/dieter/.cargo/bin:/home/dieter/code/aconfmgr:/home/dieter/.pub-cache/bin:/opt/google-cloud-cli/bin:/usr/bin:/var/lib/flatpak/exports/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/dieter/.local/bin:/sbin:/home/dieter/.npm-global/bin:/home/dieter/code/kubetail:/home/dieter/go/src/github.com/junegunn/fzf/bin
I don't quite fully understand your proposed solution, but it sounds like it will make it work, so i'm all for it.
If you don't explicitly specify a Flutter SDK (such as using the dart.flutterSdkPath
setting), we will try to find a Flutter SDK from your PATH
. We do this by looking for a flutter
binary, then if it's a symlink we resolve it, and then we look at the remaining path to see if it looks like a Flutter SDK (we can't just assume a binary named flutter
is part of an SDK because in the past some users have had unrelated binaries named flutter
on their PATH
!).
The problem is out check for what "looks like a Flutter SDK" is fairly basic (if the binary is at /foo/bin/flutter
we assume /foo
is a Flutter SDK). The proposal is to expand the check to see if there are some other indications that this is a Flutter SDK (which your wrapper script would not pass). That means we'd skip over /usr/bin/flutter
in your case and continue searching. If /opt/flutter/bin
is in your PATH
then we'd fine it, but if not, we would give you a better message saying we'd failed to find Flutter and give you a "Locate SDK" button to let you manually browse to the SDK folder (which we'd then write into the dart.flutterSdkPath
setting).
That said, the details are probably not that important to you - I'll get a fix into the pre-release and you can test it out and if it still doesn't seem to work as expected, we can refine it :-)
I suppose I could also try removing /usr/bin/flutter
. The AUR package installs it but I wasn't sure why so I asked the maintainer. You can see their answer here https://aur.archlinux.org/packages/flutter-bin#comment-981177 . Seems like they are trying to achieve the opposite : steer people away from writing to /opt/flutter (via unionfs ?) If any of this feels wrong to you I'm prepared to get rid of the package and follow the manual flutter installation guide. I've used other packages in the past it never seems to quite fit the idea of the flutter developers (who want to install in a writeable dir) but packages are usually installed systemwide (outside of home) where regular users don't have write permissions (although some group permissions magic fixes that but it's not considered "pure")
I suppose I could also try removing
/usr/bin/flutter
.
If you're just trying to get things working for you, you could also just put /opt/flutter
in your PATH
ahead of /usr
, or you could add:
"dart.flutterSdkPath": "/opt/flutter",
...to your VS Code user settings. I think we should make Dart-Code handle this case better though, so we can automatically detect it for the benefit of other/future users :)
The AUR package installs it but I wasn't sure why so I asked the maintainer. You can see their answer here https://aur.archlinux.org/packages/flutter-bin#comment-981177 . Seems like they are trying to achieve the opposite : steer people away from writing to /opt/flutter (via unionfs ?)
I read that, but I'm afraid I don't entirely understand it (I'm not very familiar with how these things work on Linux). It's true that Flutter requires write access to its own folder, and I have seen some complaints about that from a number of package managers (because they really want to just install a read-only package and have any writing done elsewhere).
The simplest way to install Flutter IMO is to just git clone
it somewhere and then add the bin
folder to PATH
. However, it's not clear to me from the thread above if there are other packages depending on a Flutter package, which probably complicates things a little (although it's not clear to me what depending on a Flutter package really means - software built with Flutter would presumably distribute compiled apps and not need a Flutter SDK?).
If you're just trying to get things working for you, you could also just put /opt/flutter in your PATH ahead of /usr,
you mean /opt/flutter/bin ahead of /usr/bin, and indeed, this seems to work very well. doctor finds 0 issues and i can "flutter run" my apps just fine.
I read that, but I'm afraid I don't entirely understand it (I'm not very familiar with how these things work on Linux).
so basically this particular package creates a "union filesystem" which is a new special directory within our usere's (mine) home directory, that we use as our flutter SDK directory. behind the scenes, all reads "secretly" are served from the real sdk dir in /opt/flutter, and writes go to a special directory (also in our home folder) that only holds written files, not the full SDK dir. so this is kindof best of both worlds. packaging best practices are held up (system wide read only installation) while keeping flutter happy (allowing writes), at the cost of extra, arguably unnecessary complication..
However, it's not clear to me from the thread above if there are other packages depending on a Flutter package, which probably complicates things a little (although it's not clear to me what depending on a Flutter package really means - software built with Flutter would presumably distribute compiled apps and not need a Flutter SDK?).
this is the main reason i'm trying to use a formal package rather than just installing it myself in my home dir, because other flutter apps are built as source packages, so installing them depends on the flutter package to provide the SDK (regardless of what i may have done myself in my home directory) to build the software.
all reads "secretly" are served from the real sdk dir in /opt/flutter, and writes go to a special directory (also in our home folder) that only holds written files, not the full SDK dir. so this is kindof best of both worlds. packaging best practices are held up (system wide read only installation) while keeping flutter happy (allowing writes), at the cost of extra, arguably unnecessary complication..
Ah, got it - that sounds reasonable. Although it's not clear to me why it needs the wrapper script for this - why can't /opt/flutter just be on path without a wrapper script?
because other flutter apps are built as source packages
Ah, I guess this makes some sense because it's much more portable.
I'll see what I can do to improve this. At worst, we'll prompt you to locate the SDK manually (instead of the confusing message we currently show), but if we can find /opt/flutter
automatically, that would just avoid this altogether. If /opt/flutter
is a common location for some linux distros, we could add that to the search list so even if it's not on PATH itself, we could find Flutter there when we don't find it anywhere else in the PATH
.
Although it's not clear to me why it needs the wrapper script for this - why can't /opt/flutter just be on path without a wrapper script?
The wrapper script is needed to set up the union filesystem "on-demand".
Looking forward to your tweak(s) :-)
Note that flutter binaries or scripts (outside the sdk dir) can still exec() another flutter binary (inside the sdk dir). That's what's happening when using this package. It probably fails the check because it's not a symlink, yet in practice it works similarly
Your idea to look in /opt/flutter seems like a good one, even if this would bypass what the package is trying to do. That said, for my needs it will work because I gave myself write permissions to /opt/flutter but others may expect the unionfs wrapper to work. Not sure if from your perspective that's something you want to support. I have another idea that's maybe not so great but would solve this maybe more comprehensively: is there any config file the user could put either in the sdk dir or their home dir allowing us to vouch that a given bin/flutter really does call another flutter in the sdk dir, eg via fork/exec . (which I assume is not easily detectable with your scripts )
I suppose what you probably ultimately really care about, is not so much that the flutter bin is inside the SDK dir per se, but that 1) whichever flutter bin/script is used, it matches the desired sdk version 2) whenever the sdk version is changed, the flutter bin/script is adjusted accordingly
You could check the first quite easily. And technically you could also validate the 2nd, but of course switching SDK versions automatically any time you want to do your check, sounds pretty bad. But maybe the first check is the one that matters most
The wrapper script is needed to set up the union filesystem "on-demand".
Is this just something that needs to happen the first time? Is it fair for Dart-Code to just ignore this and assume it will always have happened? I'm not familiar with the install flow here but there are so many package managers that work differently, I really don't want to add special cases for them all (we actually already have some special casing to handle something very similar to this that was added for Snap... it was made generic, but Snap uses a symlink to a Snap binary instead of a wrapper script, so that support doesn't help here).
I think it's probably fair to say in the case where a user manages to set this up without the unionfs, they can just close VS Code, run flutter doctor
from the terminal, and then everything should be fine (this is likely to be the first debugging step anyway).
is there any config file the user could put either in the sdk dir or their home dir allowing us to vouch that a given bin/flutter really does call another flutter in the sdk
This won't work because we're not looking for a flutter
binary, we're looking for an SDK because we need to launch other tools from it too (for example we need to run {flutter-sdk}/bin/cache/dart-sdk/bin/dart language-server
for the language server). We just use the binary to find the SDK, and then we always use absolute paths into that SDK to run all tools (this makes it easier to decouple the selected SDK from what's on PATH
, because we support switching between SDKs within VS Code).
I've pushed a new pre-release version of the Dart extension (v3.93.20240708) that will:
/opt/flutter
to a list of fallback places to searchBetween these, I think they'll solve your issue (as long as /opt/flutter
is writable with the unionfs.. otherwise you'd need to have run flutter
from a terminal first.. we could investigate additional options for this if it turns out to be a common case).
It might take 10-15 mins for the pre-release to show up, you'll want to install it, remove /opt/flutter
from the start of PATH
, and then try creating a new Flutter project (Flutter: New Project) without having an existing Flutter project open (since if you have an open project, we will probably discover the SDK via its .dart_tool/package_config.json
file).
You should be able to use Dart: Open Extension Log to verify the search paths (that /usr
is not located as an SDK, and /opt/flutter
is at the end of the search list).
I get this notification when starting vscode. Yet, flutter doctor shows everything is OK, and the "show log" button also shows a logfile which shows that actually, it can find dart. full log output here: https://gist.github.com/Dieterbe/8dc655aa221d497726018543e8d0a477
the flutter doctor output is this:
Screenshots If applicable, add screenshots to help explain your problem.
Please complete the following information:
You can run the Dart: Collect Diagnostic Information command from the VS Code command palette (
F1
) to easily capture this information or provide it manually.