blob: 1914ee258f8766ee64a8d1984de385c1360fb4e5 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../artifacts.dart';
import '../base/common.dart';
import '../base/context.dart';
import '../base/process.dart';
import '../base/version.dart';
import '../build_info.dart';
import '../globals.dart' as globals;
import '../macos/xcode.dart';
const bool kBitcodeEnabledDefault = false;
Future<void> validateBitcode(BuildMode buildMode, TargetPlatform targetPlatform, EnvironmentType environmentType) async {
final Artifacts? localArtifacts = globals.artifacts;
final String? flutterFrameworkPath = localArtifacts?.getArtifactPath(
Artifact.flutterFramework,
mode: buildMode,
platform: targetPlatform,
environmentType: environmentType,
);
final Xcode? xcode = context.get<Xcode>();
final RunResult? clangResult = await xcode?.clang(<String>['--version']);
final String? clangVersion = clangResult?.stdout.split('\n').first;
final String? engineClangVersion = flutterFrameworkPath == null
? null
: globals.plistParser.getStringValueFromFile(
globals.fs.path.join(flutterFrameworkPath, 'Info.plist'),
'ClangVersion',
);
final Version engineClangSemVer = _parseVersionFromClang(engineClangVersion);
final Version clangSemVer = _parseVersionFromClang(clangVersion);
if (engineClangSemVer > clangSemVer) {
throwToolExit(
'The Flutter.framework at $flutterFrameworkPath was built '
'with "${engineClangVersion ?? 'unknown'}", but the current version '
'of clang is "$clangVersion". This will result in failures when trying to '
'archive an IPA. To resolve this issue, update your version of Xcode to '
'at least $engineClangSemVer.',
);
}
}
Version _parseVersionFromClang(String? clangVersion) {
final RegExp pattern = RegExp(r'Apple (LLVM|clang) version (\d+\.\d+\.\d+) ');
Never invalid() {
throwToolExit('Unable to parse Clang version from "$clangVersion". '
'Expected a string like "Apple (LLVM|clang) #.#.# (clang-####.#.##.#)".');
}
if (clangVersion == null || clangVersion.isEmpty) {
invalid();
}
final RegExpMatch? match = pattern.firstMatch(clangVersion);
if (match == null || match.groupCount != 2) {
invalid();
}
final Version? version = Version.parse(match.group(2));
if (version == null) {
invalid();
}
return version;
}