@@ -16,6 +16,7 @@ import (
1616 "github.com/go-flutter-desktop/hover/internal/androidmanifest"
1717 "github.com/go-flutter-desktop/hover/internal/build"
1818 "github.com/go-flutter-desktop/hover/internal/config"
19+ "github.com/go-flutter-desktop/hover/internal/darwinhacks"
1920 "github.com/go-flutter-desktop/hover/internal/enginecache"
2021 "github.com/go-flutter-desktop/hover/internal/fileutils"
2122 "github.com/go-flutter-desktop/hover/internal/log"
@@ -216,16 +217,14 @@ func subcommandBuild(targetOS string, packagingTask packaging.Task, vmArguments
216217 if ! buildOrRunDocker {
217218 packagingTask .AssertSupported ()
218219 }
219-
220- if ! buildOrRunSkipFlutter {
221- cleanBuildOutputsDir (targetOS )
222- buildFlutterBundle (targetOS )
223- }
224220 if buildOrRunDocker {
221+ removeBrokenBundleFilesForDocker ()
225222 var buildFlags []string
226223 buildFlags = append (buildFlags , commonFlags ()... )
227- buildFlags = append (buildFlags , "--skip-flutter" )
228224 buildFlags = append (buildFlags , "--skip-engine-download" )
225+ if buildOrRunSkipFlutter {
226+ buildFlags = append (buildFlags , "--skip-flutter" )
227+ }
229228 if buildOrRunSkipEmbedder {
230229 buildFlags = append (buildFlags , "--skip-embedder" )
231230 }
@@ -242,7 +241,12 @@ func subcommandBuild(targetOS string, packagingTask packaging.Task, vmArguments
242241 buildFlags = append (buildFlags , "--profile" )
243242 }
244243 dockerHoverBuild (targetOS , packagingTask , buildFlags , nil )
244+ removeBrokenBundleFilesForDocker ()
245245 } else {
246+ if ! buildOrRunSkipFlutter {
247+ cleanBuildOutputsDir (targetOS )
248+ buildFlutterBundle (targetOS )
249+ }
246250 if ! buildOrRunSkipEmbedder {
247251 buildGoBinary (targetOS , vmArguments )
248252 }
@@ -254,6 +258,19 @@ func subcommandBuild(targetOS string, packagingTask packaging.Task, vmArguments
254258 }
255259}
256260
261+ // removeBrokenBundleFilesForDocker removes some files, because they don't work in the container or after something ran in the container
262+ func removeBrokenBundleFilesForDocker () {
263+ for _ , file := range []string {".packages" , ".dart_tool" } {
264+ if _ , err := os .Stat (file ); err == nil || os .IsExist (err ) {
265+ err := os .RemoveAll (file )
266+ if err != nil {
267+ log .Errorf ("Failed to remove %s: %v" , file , err )
268+ os .Exit (1 )
269+ }
270+ }
271+ }
272+ }
273+
257274// initBuildParameters is used to initialize all the build parameters. It sets
258275// fallback values based on config or defaults for values that have not
259276// explicitly been set through flags.
@@ -313,17 +330,39 @@ func initBuildParameters(targetOS string, defaultBuildOrRunMode build.Mode) {
313330 buildOrRunMode = build .ProfileMode
314331 }
315332
316- if buildOrRunMode .IsAot && targetOS != runtime .GOOS && ! buildIgnoreHostOS {
317- log .Errorf ("AOT builds currently only work on their host OS" )
318- os .Exit (1 )
319- }
333+ validateBuildParameters (targetOS )
320334
321335 engineCachePath = enginecache .EngineCachePath (targetOS , buildOrRunCachePath , buildOrRunMode )
322336 if ! buildSkipEngineDownload {
323337 enginecache .ValidateOrUpdateEngine (targetOS , buildOrRunCachePath , buildOrRunEngineVersion , buildOrRunMode )
324338 }
325339}
326340
341+ func validateBuildParameters (targetOS string ) {
342+ if buildOrRunMode .IsAot && targetOS != runtime .GOOS && ! buildIgnoreHostOS {
343+ if targetOS == "windows" && runtime .GOOS != targetOS {
344+ if path , err := exec .LookPath ("wine" ); (err != nil || len (path ) == 0 ) && ! buildOrRunDocker {
345+ // Skip checking for wine if using docker, but still being on host system
346+ log .Errorf ("To cross-compile AOT apps for windows on %s install wine from your package manager or https://www.winehq.org/ or use the `--docker` flag" , runtime .GOOS )
347+ os .Exit (1 )
348+ }
349+ } else if targetOS == "darwin" && runtime .GOOS == "linux" {
350+ if buildOrRunDocker {
351+ // Darling doesn't work in a docker container so it should fail when trying to use docker
352+ log .Errorf ("It is not possible to cross-compile AOT apps for darwin using docker" )
353+ log .Errorf ("To cross-compile AOT apps for darwin on %s install darling from your package manager or https://www.darlinghq.org/" , runtime .GOOS )
354+ os .Exit (1 )
355+ } else if path , err := exec .LookPath ("darling" ); err != nil || len (path ) == 0 {
356+ log .Errorf ("To cross-compile AOT apps for darwin on %s install darling from your package manager or https://www.darlinghq.org/" , runtime .GOOS )
357+ os .Exit (1 )
358+ }
359+ } else {
360+ log .Errorf ("AOT builds currently only work on their host OS" )
361+ os .Exit (1 )
362+ }
363+ }
364+ }
365+
327366func commonFlags () []string {
328367 var f []string
329368 if buildOrRunFlutterTarget != config .BuildTargetDefault {
@@ -434,52 +473,82 @@ func buildFlutterBundle(targetOS string) {
434473 log .Errorf ("Failed to remove unused kernel_blob.bin: %v" , err )
435474 os .Exit (1 )
436475 }
476+
477+ useWine := targetOS == "windows" && runtime .GOOS != targetOS
478+ useDarling := targetOS == "darwin" && runtime .GOOS != targetOS
479+
480+ if useDarling {
481+ darwinhacks .ChangePackagesFilePath (true )
482+ }
483+
437484 dart := filepath .Join (engineCachePath , "dart" + build .ExecutableExtension (targetOS ))
438485 genSnapshot := filepath .Join (engineCachePath , "gen_snapshot" + build .ExecutableExtension (targetOS ))
439486 kernelSnapshot := filepath .Join (build .OutputDirectoryPath (targetOS , buildOrRunMode ), "kernel_snapshot.dill" )
440487 elfSnapshot := filepath .Join (build .OutputDirectoryPath (targetOS , buildOrRunMode ), "libapp.so" )
441- cmdGenerateKernelSnapshot := exec .Command (
442- dart ,
443- filepath .Join (engineCachePath , "gen" , "frontend_server.dart.snapshot" ),
444- "--sdk-root=" + filepath .Join (engineCachePath , "flutter_patched_sdk" ),
488+ frontendServerSnapshot := filepath .Join (engineCachePath , "gen" , "frontend_server.dart.snapshot" )
489+ flutterPatchedSdk := filepath .Join (engineCachePath , "flutter_patched_sdk" )
490+ generateKernelSnapshotCommand := []string {
491+ darwinhacks .RewriteDarlingPath (useDarling , dart ),
492+ darwinhacks .RewriteDarlingPath (useDarling , frontendServerSnapshot ),
493+ "--sdk-root=" + darwinhacks .RewriteDarlingPath (useDarling , flutterPatchedSdk ),
445494 "--target=flutter" ,
446495 "--aot" ,
447496 "--tfa" ,
448497 "-Ddart.vm.product=true" ,
449498 "--packages=.packages" ,
450- "--output-dill=" + kernelSnapshot ,
499+ "--output-dill=" + darwinhacks . RewriteDarlingPath ( useDarling , kernelSnapshot ) ,
451500 buildOrRunFlutterTarget ,
501+ }
502+ if useWine {
503+ generateKernelSnapshotCommand = append ([]string {"wine" }, generateKernelSnapshotCommand ... )
504+ }
505+ if useDarling {
506+ generateKernelSnapshotCommand = append ([]string {"darling" , "shell" }, generateKernelSnapshotCommand ... )
507+ }
508+ cmdGenerateKernelSnapshot := exec .Command (
509+ generateKernelSnapshotCommand [0 ],
510+ generateKernelSnapshotCommand [1 :]... ,
452511 )
512+ cmdGenerateKernelSnapshot .Stdout = os .Stdout
453513 cmdGenerateKernelSnapshot .Stderr = os .Stderr
454514 log .Infof ("Generating kernel snapshot" )
455- output , err := cmdGenerateKernelSnapshot .Output ()
515+ err = cmdGenerateKernelSnapshot .Run ()
516+ if useDarling {
517+ // Change back paths even if the command failed
518+ darwinhacks .ChangePackagesFilePath (false )
519+ }
456520 if err != nil {
457521 log .Errorf ("Generating kernel snapshot failed: %v" , err )
458- log .Errorf (string (output ))
459522 os .Exit (1 )
460523 }
461524 generateAotSnapshotCommand := []string {
462- genSnapshot ,
525+ darwinhacks . RewriteDarlingPath ( useDarling , genSnapshot ) ,
463526 "--no-causal-async-stacks" ,
464527 "--lazy-async-stacks" ,
465528 "--deterministic" ,
466529 "--snapshot_kind=app-aot-elf" ,
467- "--elf=" + elfSnapshot ,
530+ "--elf=" + darwinhacks .RewriteDarlingPath (useDarling , elfSnapshot ),
531+ }
532+ if useWine {
533+ generateAotSnapshotCommand = append ([]string {"wine" }, generateAotSnapshotCommand ... )
534+ }
535+ if useDarling {
536+ generateAotSnapshotCommand = append ([]string {"darling" , "shell" }, generateAotSnapshotCommand ... )
468537 }
469538 if buildOrRunMode == build .ReleaseMode {
470539 generateAotSnapshotCommand = append (generateAotSnapshotCommand , "--strip" )
471540 }
472- generateAotSnapshotCommand = append (generateAotSnapshotCommand , kernelSnapshot )
541+ generateAotSnapshotCommand = append (generateAotSnapshotCommand , darwinhacks . RewriteDarlingPath ( useDarling , kernelSnapshot ) )
473542 cmdGenerateAotSnapshot := exec .Command (
474543 generateAotSnapshotCommand [0 ],
475544 generateAotSnapshotCommand [1 :]... ,
476545 )
546+ cmdGenerateAotSnapshot .Stdout = os .Stdout
477547 cmdGenerateAotSnapshot .Stderr = os .Stderr
478548 log .Infof ("Generating ELF snapshot" )
479- output , err = cmdGenerateAotSnapshot .Output ()
549+ err = cmdGenerateAotSnapshot .Run ()
480550 if err != nil {
481551 log .Errorf ("Generating AOT snapshot failed: %v" , err )
482- log .Errorf (string (output ))
483552 os .Exit (1 )
484553 }
485554 err = os .Remove (kernelSnapshot )
@@ -594,10 +663,6 @@ func buildGoBinary(targetOS string, vmArguments []string) {
594663 log .Warnf ("The '--opengl=none' flag makes go-flutter incompatible with texture plugins!" )
595664 }
596665
597- if targetOS == "darwin" && buildOrRunMode != build .DebugMode {
598- darwinDyldHack (filepath .Join (build .OutputDirectoryPath (targetOS , buildOrRunMode ), build .EngineFiles (targetOS , buildOrRunMode )[0 ]))
599- }
600-
601666 buildCommandString := buildCommand (targetOS , vmArguments , build .OutputBinaryPath (config .GetConfig ().GetExecutableName (pubspec .GetPubSpec ().Name ), targetOS , buildOrRunMode ))
602667 cmdGoBuild := exec .Command (buildCommandString [0 ], buildCommandString [1 :]... )
603668 cmdGoBuild .Dir = filepath .Join (wd , build .BuildPath )
@@ -616,29 +681,7 @@ func buildGoBinary(targetOS string, vmArguments []string) {
616681 }
617682 log .Infof ("Successfully compiled executable binary for %s" , targetOS )
618683 if targetOS == "darwin" && buildOrRunMode != build .DebugMode {
619- darwinDyldHack (build .OutputBinaryPath (config .GetConfig ().GetExecutableName (pubspec .GetPubSpec ().Name ), targetOS , buildOrRunMode ))
620- }
621- }
622-
623- // darwinDyldHack is a nasty hack to get the linking working. After fiddling a lot of hours with CGO linking
624- // this was the only solution I could come up with and it works. I guess something would need to be changed in the engine
625- // builds to make this obsolete, but this hack does it for now.
626- func darwinDyldHack (path string ) {
627- cmdInstallNameTool := exec .Command (
628- "install_name_tool" ,
629- "-change" ,
630- "./libflutter_engine.dylib" ,
631- "@executable_path/libflutter_engine.dylib" ,
632- "-id" ,
633- "@executable_path/libflutter_engine.dylib" ,
634- path ,
635- )
636- cmdInstallNameTool .Stderr = os .Stderr
637- output , err := cmdInstallNameTool .Output ()
638- if err != nil {
639- log .Errorf ("install_name_tool failed: %v" , err )
640- log .Errorf (string (output ))
641- os .Exit (1 )
684+ darwinhacks .DyldHack (build .OutputBinaryPath (config .GetConfig ().GetExecutableName (pubspec .GetPubSpec ().Name ), targetOS , buildOrRunMode ))
642685 }
643686}
644687
0 commit comments