-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
When native assets are looked up at runtime with a 'relative' path, the path is resolved against the platform script path:
sdk/runtime/lib/ffi_dynamic_library.cc
Lines 402 to 423 in be95daf
| } else if (asset_type.Equals(Symbols::relative())) { | |
| const auto& platform_script_uri = String::Handle( | |
| zone, | |
| String::NewFormatted( | |
| "%s%s", file_schema, | |
| String::Handle(zone, GetPlatformScriptPath(thread)).ToCString())); | |
| const char* target_uri = nullptr; | |
| char* path_cstr = path.ToMallocCString(); | |
| #if defined(DART_TARGET_OS_WINDOWS) | |
| ReplaceBackSlashes(path_cstr); | |
| #endif | |
| const bool resolved = | |
| ResolveUri(path_cstr, platform_script_uri.ToCString(), &target_uri); | |
| free(path_cstr); | |
| if (!resolved) { | |
| *error = OS::SCreate(/*use malloc*/ nullptr, | |
| "Failed to resolve '%s' relative to '%s'.", | |
| path.ToCString(), platform_script_uri.ToCString()); | |
| } else { | |
| const char* target_path = target_uri + file_schema_length; | |
| handle = LoadDynamicLibrary(target_path, error); | |
| } |
However, if this platform script path contains symlinks, these are not resolved.
Consider the following directory structure.
* temp
* foo
* kernel-snapshot
* my_asset.so
* bar
* baz -> ../foo/kernel-snapshot
Assuming the native assets mapping is ['relative', './my_asset.so'] for some asset, running dart /temp/bar/baz will try to look up the asset in /temp/bar/my_asset.so.
To fix this, we could resolve try to resolve symlinks in the platform script path before doing any relative path resolution.
The question is whether that is the right thing to do yes or no. Consider the following directory structure:
* temp
* foo
* kernel-snapshot
* bar
* baz -> ../foo/kernel-snapshot
* my_asset.so
In this case, first resolving the symlinks would make the same resolution fail.
Given how common it is to symlink executables,
$ ls -lah /usr/bin/clang
lrwxrwxrwx 1 root root 24 Sep 13 2023 /usr/bin/clang -> ../lib/llvm-16/bin/clang
we should most likely not care about the latter case and resolve the symlinks eagerly.
Especially, in the case where we dart build exe, when we start building self-contained executable bundles.
To have consistency with executable bundles, and bundles with snapshots, we should do the same for snapshots.
- kernel snapshot
- appjit snapshot
- aot snapshot
-
dart build([native-assets] Windows lookup fails when exe is symlinked #55207)
Reproduction: https://dart-review.googlesource.com/c/sdk/+/361881/4
And for good measure, it should work on all operating systems:
- Linux
- MacOS
- Windows