run method
Future<void>
run({
- required BuildConfig buildConfig,
- required BuildOutput buildOutput,
- required Logger? logger,
Runs the Golang Compiler.
Completes with an error if the build fails.
Implementation
Future<void> run({
required BuildConfig buildConfig,
required BuildOutput buildOutput,
required Logger? logger,
}) async {
final outDir = buildConfig.outputDirectory;
final packageRoot = buildConfig.packageRoot;
await Directory.fromUri(outDir).create(recursive: true);
var linkMode = _linkMode(buildConfig.linkModePreference);
final libUri = outDir.resolve(
buildConfig.targetOS.libraryFileName(name, linkMode),
);
final bridgePath = packageRoot.resolveUri(Uri.file(this.bridgePath));
final resolver = CompilerResolver(buildConfig: buildConfig, logger: logger);
if (!buildConfig.dryRun) {
final compiler = await resolver.resolveCompiler();
var buildMode = linkMode == StaticLinking() ? "c-archive" : "c-shared";
var goLib = libUri;
final env = {
"CGO_ENABLED": "1",
};
String buildArch;
switch (buildConfig.targetArchitecture) {
case Architecture.arm:
buildArch = "arm";
case Architecture.arm64:
buildArch = "arm64";
case Architecture.ia32:
buildArch = "386";
case Architecture.x64:
buildArch = "amd64";
default:
throw Exception("Unknown architecture");
}
String buildOs;
switch (buildConfig.targetOS) {
case OS.windows:
buildOs = "windows";
case OS.linux:
buildOs = "linux";
case OS.android:
buildOs = "android";
// The Android Gradle plugin does not honor API level 19 and 20 when
// invoking clang. Mimic that behavior here.
// See https://github.com/dart-lang/native/issues/171.
final minimumApi =
buildConfig.targetArchitecture == Architecture.riscv64 ? 35 : 21;
final targetAndroidNdkApi =
max(buildConfig.targetAndroidNdkApi!, minimumApi);
final cc = compiler.uri.resolve(
'./${androidNdkClangTargetFlags[buildConfig.targetArchitecture]!}$targetAndroidNdkApi-clang');
env["CC"] = cc.toFilePath();
case OS.iOS:
buildOs = "ios";
buildMode = "c-archive";
goLib = outDir.resolve('out.o');
case OS.macOS:
buildOs = "darwin";
default:
throw Exception("Unknown os");
}
env["GOOS"] = buildOs;
env["GOARCH"] = buildArch;
await runProcess(
executable: Uri.file("go"),
environment: env,
arguments: [
"build",
"-buildmode=$buildMode",
if (buildConfig.buildMode != BuildMode.debug) '-ldflags=-s -w',
'-o',
goLib.toFilePath(),
bridgePath.toFilePath(),
],
logger: logger,
captureOutput: false,
throwOnUnexpectedExitCode: true,
);
if (buildConfig.targetOS == OS.iOS) {
//xcrun -sdk iphoneos clang -arch armv7 -fpic -shared -Wl,-all_load
// libmystatic.a -framework Corefoundation -o libmydynamic.dylib
await runProcess(
executable: compiler.uri,
arguments: [
'-fpic',
'-shared',
'-Wl,-all_load,-force_load',
goLib.toFilePath(),
'-framework',
'CoreFoundation',
'-o',
libUri.toFilePath(),
],
logger: logger,
captureOutput: false,
throwOnUnexpectedExitCode: true,
);
}
}
if (assetName != null) {
buildOutput.addAssets([
NativeCodeAsset(
package: buildConfig.packageName,
name: assetName!,
file: libUri,
linkMode: linkMode,
os: buildConfig.targetOS,
architecture:
buildConfig.dryRun ? null : buildConfig.targetArchitecture,
)
]);
}
if (!buildConfig.dryRun) {
final sources = [
bridgePath,
for (final source in this.sources)
packageRoot.resolveUri(Uri.file(source)),
];
final dartBuildFiles = [
for (final source in this.dartBuildFiles) packageRoot.resolve(source),
];
final sourceFiles = await Stream.fromIterable(sources)
.asyncExpand(
(path) => Directory(path.toFilePath())
.list(recursive: true)
.where((entry) => entry is File)
.map((file) => file.uri),
)
.toList();
buildOutput.addDependencies({
...sourceFiles,
...dartBuildFiles,
});
}
}