diff --git a/packages/vector_graphics_compiler/CHANGELOG.md b/packages/vector_graphics_compiler/CHANGELOG.md index f246e4d0b0d..75979d49146 100644 --- a/packages/vector_graphics_compiler/CHANGELOG.md +++ b/packages/vector_graphics_compiler/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.2.6 + +* Fixes `linux-arm64` host support by selecting the Flutter engine + artifact directory from `Abi.current()` instead of a hardcoded + `linux-x64`. The same fix applies to the tessellator loader. + Resolves flutter/flutter#158865. + ## 1.2.5 * Updates allowed version range of `xml` to include up to 7.0.1. diff --git a/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart b/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart index ba0301b5308..badd0060d80 100644 --- a/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart +++ b/packages/vector_graphics_compiler/lib/src/_initialize_path_ops_io.dart @@ -4,7 +4,10 @@ // ignore_for_file: avoid_print +import 'dart:ffi' show Abi; import 'dart:io'; + +import 'engine_artifact.dart'; import 'svg/path_ops.dart'; /// Look up the location of the pathops from flutter's artifact cache. @@ -19,22 +22,17 @@ bool initializePathOpsFromFlutterCache() { return false; } - final String platform; - final String executable; - if (Platform.isWindows) { - platform = 'windows-x64'; - executable = 'path_ops.dll'; - } else if (Platform.isMacOS) { - platform = 'darwin-x64'; - executable = 'libpath_ops.dylib'; - } else if (Platform.isLinux) { - platform = 'linux-x64'; - executable = 'libpath_ops.so'; - } else { - print('path_ops not supported on ${Platform.localeName}'); + final String? subpath = engineArtifactSubpath( + windowsFile: 'path_ops.dll', + macOSFile: 'libpath_ops.dylib', + linuxFile: 'libpath_ops.so', + abi: Abi.current(), + ); + if (subpath == null) { + print('path_ops not supported on ${Abi.current()}'); return false; } - final pathops = '${cacheRoot.path}/artifacts/engine/$platform/$executable'; + final pathops = '${cacheRoot.path}/artifacts/engine/$subpath'; if (!File(pathops).existsSync()) { print('Could not locate libpathops at $pathops.'); print('Ensure you are on a supported version of flutter and then run '); diff --git a/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart b/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart index 735f633687d..9b138a21ddd 100644 --- a/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart +++ b/packages/vector_graphics_compiler/lib/src/_initialize_tessellator_io.dart @@ -4,7 +4,10 @@ // ignore_for_file: avoid_print +import 'dart:ffi' show Abi; import 'dart:io'; + +import 'engine_artifact.dart'; import 'svg/tessellator.dart'; /// Look up the location of the tessellator from flutter's artifact cache. @@ -19,23 +22,17 @@ bool initializeTessellatorFromFlutterCache() { return false; } - final String platform; - final String executable; - if (Platform.isWindows) { - platform = 'windows-x64'; - executable = 'libtessellator.dll'; - } else if (Platform.isMacOS) { - platform = 'darwin-x64'; - executable = 'libtessellator.dylib'; - } else if (Platform.isLinux) { - platform = 'linux-x64'; - executable = 'libtessellator.so'; - } else { - print('Tesselation not supported on ${Platform.localeName}'); + final String? subpath = engineArtifactSubpath( + windowsFile: 'libtessellator.dll', + macOSFile: 'libtessellator.dylib', + linuxFile: 'libtessellator.so', + abi: Abi.current(), + ); + if (subpath == null) { + print('Tesselation not supported on ${Abi.current()}'); return false; } - final tessellator = - '${cacheRoot.path}/artifacts/engine/$platform/$executable'; + final tessellator = '${cacheRoot.path}/artifacts/engine/$subpath'; if (!File(tessellator).existsSync()) { print('Could not locate libtessellator at $tessellator.'); print('Ensure you are on a supported version of flutter and then run '); diff --git a/packages/vector_graphics_compiler/lib/src/engine_artifact.dart b/packages/vector_graphics_compiler/lib/src/engine_artifact.dart new file mode 100644 index 00000000000..1a304aeec9e --- /dev/null +++ b/packages/vector_graphics_compiler/lib/src/engine_artifact.dart @@ -0,0 +1,22 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ffi' show Abi; + +/// Returns the engine-artifact subpath (`/`) for [abi], +/// or `null` if the host is unsupported. +String? engineArtifactSubpath({ + required String windowsFile, + required String macOSFile, + required String linuxFile, + required Abi abi, +}) { + return switch (abi) { + Abi.windowsX64 || Abi.windowsArm64 => 'windows-x64/$windowsFile', + Abi.macosX64 || Abi.macosArm64 => 'darwin-x64/$macOSFile', + Abi.linuxX64 => 'linux-x64/$linuxFile', + Abi.linuxArm64 => 'linux-arm64/$linuxFile', + _ => null, + }; +} diff --git a/packages/vector_graphics_compiler/pubspec.yaml b/packages/vector_graphics_compiler/pubspec.yaml index 31dbd190957..db216b08885 100644 --- a/packages/vector_graphics_compiler/pubspec.yaml +++ b/packages/vector_graphics_compiler/pubspec.yaml @@ -2,7 +2,7 @@ name: vector_graphics_compiler description: A compiler to convert SVGs to the binary format used by `package:vector_graphics`. repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics_compiler issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22 -version: 1.2.5 +version: 1.2.6 executables: vector_graphics_compiler: diff --git a/packages/vector_graphics_compiler/test/engine_artifact_test.dart b/packages/vector_graphics_compiler/test/engine_artifact_test.dart new file mode 100644 index 00000000000..03c43bb8202 --- /dev/null +++ b/packages/vector_graphics_compiler/test/engine_artifact_test.dart @@ -0,0 +1,94 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ffi'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:vector_graphics_compiler/src/engine_artifact.dart'; + +void main() { + String? pathOps(Abi abi) => engineArtifactSubpath( + windowsFile: 'path_ops.dll', + macOSFile: 'libpath_ops.dylib', + linuxFile: 'libpath_ops.so', + abi: abi, + ); + + String? tessellator(Abi abi) => engineArtifactSubpath( + windowsFile: 'libtessellator.dll', + macOSFile: 'libtessellator.dylib', + linuxFile: 'libtessellator.so', + abi: abi, + ); + + group('engineArtifactSubpath', () { + group('Windows', () { + test('windowsX64 -> windows-x64/', () { + expect(pathOps(Abi.windowsX64), 'windows-x64/path_ops.dll'); + expect(tessellator(Abi.windowsX64), 'windows-x64/libtessellator.dll'); + }); + + test('windowsArm64 falls back to windows-x64 (x64 emulation)', () { + expect(pathOps(Abi.windowsArm64), 'windows-x64/path_ops.dll'); + }); + }); + + group('macOS', () { + test('macosX64 -> darwin-x64/', () { + expect(pathOps(Abi.macosX64), 'darwin-x64/libpath_ops.dylib'); + expect(tessellator(Abi.macosX64), 'darwin-x64/libtessellator.dylib'); + }); + + test('macosArm64 -> darwin-x64/', () { + expect(pathOps(Abi.macosArm64), 'darwin-x64/libpath_ops.dylib'); + }); + }); + + group('Linux', () { + test('linuxX64 -> linux-x64/', () { + expect(pathOps(Abi.linuxX64), 'linux-x64/libpath_ops.so'); + expect(tessellator(Abi.linuxX64), 'linux-x64/libtessellator.so'); + }); + + test('linuxArm64 -> linux-arm64/', () { + expect(pathOps(Abi.linuxArm64), 'linux-arm64/libpath_ops.so'); + expect(tessellator(Abi.linuxArm64), 'linux-arm64/libtessellator.so'); + }); + }); + + group('unsupported hosts return null', () { + test('android', () { + expect(pathOps(Abi.androidArm64), isNull); + }); + + test('iOS', () { + expect(pathOps(Abi.iosArm64), isNull); + }); + + test('fuchsia', () { + expect(pathOps(Abi.fuchsiaArm64), isNull); + }); + + test('linuxArm (32-bit)', () { + expect(pathOps(Abi.linuxArm), isNull); + }); + + test('linuxIA32', () { + expect(pathOps(Abi.linuxIA32), isNull); + }); + + test('linuxRiscv32', () { + expect(pathOps(Abi.linuxRiscv32), isNull); + }); + + test('linuxRiscv64', () { + expect(pathOps(Abi.linuxRiscv64), isNull); + }); + + test('windowsIA32', () { + expect(pathOps(Abi.windowsIA32), isNull); + }); + }); + }); +}