Fix the issues with the profile add button to cover the edit button Adapt LoadBalance and Relay Add arm Fix android notification icon error
407 lines
10 KiB
Dart
407 lines
10 KiB
Dart
// ignore_for_file: avoid_print
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:args/command_runner.dart';
|
|
import 'package:path/path.dart';
|
|
|
|
enum PlatformType {
|
|
windows,
|
|
linux,
|
|
android,
|
|
macos,
|
|
}
|
|
|
|
enum Arch { amd64, arm64, arm }
|
|
|
|
class BuildLibItem {
|
|
PlatformType platform;
|
|
Arch arch;
|
|
String archName;
|
|
|
|
BuildLibItem({
|
|
required this.platform,
|
|
required this.arch,
|
|
required this.archName,
|
|
});
|
|
|
|
String get dynamicLibExtensionName {
|
|
final String extensionName;
|
|
switch (platform) {
|
|
case PlatformType.android || PlatformType.linux:
|
|
extensionName = "so";
|
|
break;
|
|
case PlatformType.windows:
|
|
extensionName = "dll";
|
|
break;
|
|
case PlatformType.macos:
|
|
extensionName = "dylib";
|
|
break;
|
|
}
|
|
return extensionName;
|
|
}
|
|
|
|
String get os {
|
|
if (platform == PlatformType.macos) {
|
|
return "darwin";
|
|
}
|
|
return platform.name;
|
|
}
|
|
}
|
|
|
|
class Build {
|
|
static List<BuildLibItem> get buildItems => [
|
|
BuildLibItem(
|
|
platform: PlatformType.macos,
|
|
arch: Arch.amd64,
|
|
archName: 'amd64',
|
|
),
|
|
BuildLibItem(
|
|
platform: PlatformType.windows,
|
|
arch: Arch.amd64,
|
|
archName: 'amd64',
|
|
),
|
|
BuildLibItem(
|
|
platform: PlatformType.android,
|
|
arch: Arch.arm,
|
|
archName: 'armeabi-v7a',
|
|
),
|
|
BuildLibItem(
|
|
platform: PlatformType.android,
|
|
arch: Arch.arm64,
|
|
archName: 'arm64-v8a',
|
|
),
|
|
BuildLibItem(
|
|
platform: PlatformType.android,
|
|
arch: Arch.amd64,
|
|
archName: 'x86_64',
|
|
),
|
|
BuildLibItem(
|
|
platform: PlatformType.linux,
|
|
arch: Arch.amd64,
|
|
archName: 'amd64',
|
|
),
|
|
];
|
|
|
|
static String get appName => "FlClash";
|
|
|
|
static String get libName => "libclash";
|
|
|
|
static String get outDir => join(current, libName);
|
|
|
|
static String get _coreDir => join(current, "core");
|
|
|
|
static String get distPath => join(current, "dist");
|
|
|
|
static String _getCc(BuildLibItem buildItem) {
|
|
final environment = Platform.environment;
|
|
if (buildItem.platform == PlatformType.android) {
|
|
final ndk = environment["ANDROID_NDK"];
|
|
assert(ndk != null);
|
|
final prebuiltDir =
|
|
Directory(join(ndk!, "toolchains", "llvm", "prebuilt"));
|
|
final prebuiltDirList = prebuiltDir.listSync();
|
|
final map = {
|
|
"armeabi-v7a": "armv7a-linux-androideabi21-clang",
|
|
"arm64-v8a": "aarch64-linux-android21-clang",
|
|
"x86": "i686-linux-android21-clang",
|
|
"x86_64": "x86_64-linux-android21-clang"
|
|
};
|
|
return join(
|
|
prebuiltDirList.first.path,
|
|
"bin",
|
|
map[buildItem.archName],
|
|
);
|
|
}
|
|
return "gcc";
|
|
}
|
|
|
|
static get tags => "with_gvisor";
|
|
|
|
static Future<void> exec(
|
|
List<String> executable, {
|
|
String? name,
|
|
Map<String, String>? environment,
|
|
String? workingDirectory,
|
|
bool runInShell = true,
|
|
}) async {
|
|
if (name != null) print("run $name");
|
|
final process = await Process.start(
|
|
executable[0],
|
|
executable.sublist(1),
|
|
environment: environment,
|
|
workingDirectory: workingDirectory,
|
|
runInShell: runInShell,
|
|
);
|
|
process.stdout.listen((data) {
|
|
print(utf8.decode(data));
|
|
});
|
|
process.stderr.listen((data) {
|
|
print(utf8.decode(data));
|
|
});
|
|
final exitCode = await process.exitCode;
|
|
if (exitCode != 0 && name != null) throw "$name error";
|
|
}
|
|
|
|
static buildLib({
|
|
required PlatformType platform,
|
|
Arch? arch,
|
|
}) async {
|
|
final items = buildItems.where(
|
|
(element) {
|
|
return element.platform == platform && arch == null
|
|
? true
|
|
: element.arch == arch;
|
|
},
|
|
).toList();
|
|
for (final item in items) {
|
|
final outFileDir = join(
|
|
outDir,
|
|
item.platform.name,
|
|
item.archName,
|
|
);
|
|
final file = File(outFileDir);
|
|
if (file.existsSync()) {
|
|
file.deleteSync(recursive: true);
|
|
}
|
|
final outPath = join(
|
|
outFileDir,
|
|
"$libName.${item.dynamicLibExtensionName}",
|
|
);
|
|
final Map<String, String> env = {};
|
|
env["GOOS"] = item.os;
|
|
env["GOARCH"] = item.arch.name;
|
|
env["CGO_ENABLED"] = "1";
|
|
env["CC"] = _getCc(item);
|
|
if (item.platform == PlatformType.macos) {
|
|
env["CGO_CFLAGS"] = "-mmacosx-version-min=10.11";
|
|
env["CGO_LDFLAGS"] = "-mmacosx-version-min=10.11";
|
|
}
|
|
|
|
await exec(
|
|
[
|
|
"go",
|
|
"build",
|
|
"-ldflags=-w -s",
|
|
"-tags=$tags",
|
|
"-buildmode=c-shared",
|
|
"-o",
|
|
outPath,
|
|
],
|
|
name: "build libclash",
|
|
environment: env,
|
|
workingDirectory: _coreDir,
|
|
);
|
|
}
|
|
}
|
|
|
|
static List<String> getExecutable(String command) {
|
|
return command.split(" ");
|
|
}
|
|
|
|
static getDistributor() async {
|
|
final distributorDir = join(
|
|
current,
|
|
"plugins",
|
|
"flutter_distributor",
|
|
"packages",
|
|
"flutter_distributor",
|
|
);
|
|
|
|
await exec(
|
|
name: "clean distributor",
|
|
Build.getExecutable("flutter clean"),
|
|
workingDirectory: distributorDir,
|
|
);
|
|
await exec(
|
|
name: "get distributor",
|
|
Build.getExecutable("dart pub global activate -s path $distributorDir"),
|
|
);
|
|
}
|
|
|
|
static copyFile(String sourceFilePath, String destinationFilePath) {
|
|
final sourceFile = File(sourceFilePath);
|
|
if (!sourceFile.existsSync()) {
|
|
throw "SourceFilePath not exists";
|
|
}
|
|
final destinationFile = File(destinationFilePath);
|
|
final destinationDirectory = destinationFile.parent;
|
|
if (!destinationDirectory.existsSync()) {
|
|
destinationDirectory.createSync(recursive: true);
|
|
}
|
|
try {
|
|
sourceFile.copySync(destinationFilePath);
|
|
print("File copied successfully!");
|
|
} catch (e) {
|
|
print("Failed to copy file: $e");
|
|
}
|
|
}
|
|
}
|
|
|
|
class BuildCommand extends Command {
|
|
PlatformType platform;
|
|
|
|
BuildCommand({
|
|
required this.platform,
|
|
}) {
|
|
argParser.addOption(
|
|
"build",
|
|
valueHelp: [
|
|
'all',
|
|
'lib',
|
|
].join(','),
|
|
help: 'The $name build type',
|
|
);
|
|
argParser.addOption(
|
|
"arch",
|
|
valueHelp: arches.map((e) => e.name).join(','),
|
|
help: 'The $name build arch',
|
|
);
|
|
}
|
|
|
|
@override
|
|
String get description => "build $name application";
|
|
|
|
@override
|
|
String get name => platform.name;
|
|
|
|
List<Arch> get arches => Build.buildItems
|
|
.where((element) => element.platform == platform)
|
|
.map((e) => e.arch)
|
|
.toList();
|
|
|
|
Future<void> _buildLib(Arch? arch) async {
|
|
await Build.buildLib(platform: platform, arch: arch);
|
|
}
|
|
|
|
_getLinuxDependencies() async {
|
|
await Build.exec(
|
|
Build.getExecutable("sudo apt update -y"),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable("sudo apt install -y ninja-build libgtk-3-dev"),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable("sudo apt install -y libayatana-appindicator3-dev"),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable("sudo apt install -y rpm patchelf"),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable("sudo apt install -y locate"),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable("sudo apt install -y libfuse2"),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable(
|
|
"wget -O appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage",
|
|
),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable(
|
|
"chmod +x appimagetool",
|
|
),
|
|
);
|
|
await Build.exec(
|
|
Build.getExecutable(
|
|
"sudo mv appimagetool /usr/local/bin/",
|
|
),
|
|
);
|
|
}
|
|
|
|
_getMacosDependencies() async {
|
|
await Build.exec(
|
|
Build.getExecutable("npm install -g appdmg"),
|
|
);
|
|
}
|
|
|
|
_buildDistributor({
|
|
required PlatformType platform,
|
|
required String targets,
|
|
String args = '',
|
|
}) async {
|
|
await Build.getDistributor();
|
|
await Build.exec(
|
|
name: name,
|
|
Build.getExecutable(
|
|
"flutter_distributor package --skip-clean --platform ${platform.name} --targets $targets --flutter-build-args=verbose $args",
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<void> run() async {
|
|
final String build = argResults?['build'] ?? 'all';
|
|
final archName = argResults?['arch'];
|
|
final currentArches =
|
|
arches.where((element) => element.name == archName).toList();
|
|
final arch = currentArches.isEmpty ? null : currentArches.first;
|
|
await _buildLib(arch);
|
|
if (build != "all") {
|
|
return;
|
|
}
|
|
switch (platform) {
|
|
case PlatformType.windows:
|
|
_buildDistributor(
|
|
platform: platform,
|
|
targets: "exe,zip",
|
|
args: "--description amd64",
|
|
);
|
|
break;
|
|
case PlatformType.linux:
|
|
await _getLinuxDependencies();
|
|
_buildDistributor(
|
|
platform: platform,
|
|
targets: "appimage,deb,rpm",
|
|
args: "--description amd64",
|
|
);
|
|
break;
|
|
case PlatformType.android:
|
|
final targetMap = {
|
|
Arch.arm: "android-arm",
|
|
Arch.arm64: "android-arm64",
|
|
Arch.amd64: "android-x64",
|
|
};
|
|
final defaultArches = [Arch.arm, Arch.arm64, Arch.amd64];
|
|
final defaultTargets = defaultArches
|
|
.where((element) => arch == null ? true : element == arch)
|
|
.map((e) => targetMap[e])
|
|
.toList();
|
|
_buildDistributor(
|
|
platform: platform,
|
|
targets: "apk",
|
|
args:
|
|
"--flutter-build-args split-per-abi --build-target-platform ${defaultTargets.join(",")}",
|
|
);
|
|
break;
|
|
case PlatformType.macos:
|
|
await _getMacosDependencies();
|
|
_buildDistributor(
|
|
platform: platform,
|
|
targets: "dmg",
|
|
args: "--description amd64",
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
main(args) async {
|
|
final runner = CommandRunner("setup", "build Application");
|
|
runner.addCommand(BuildCommand(platform: PlatformType.android));
|
|
if (Platform.isWindows) {
|
|
runner.addCommand(BuildCommand(platform: PlatformType.windows));
|
|
}
|
|
if (Platform.isLinux) {
|
|
runner.addCommand(BuildCommand(platform: PlatformType.linux));
|
|
}
|
|
if (Platform.isMacOS) {
|
|
runner.addCommand(BuildCommand(platform: PlatformType.macos));
|
|
}
|
|
if (args.isEmpty) {
|
|
args = [Platform.operatingSystem];
|
|
}
|
|
runner.run(args);
|
|
}
|