Darwin/Mac OS host rust compilation fixes

- Don't pass `--as-needed` to the linker on Mac OS which is unsupported
  there
- Use `--force_load` rather than `--Wl,--whole-archive` on Mac OS
- Scan `rustc`'s linker arguments for `-dylib` and `-dynamiclib`, which
  it can use instead of `-shared` on Mac OS:
  https://github.com/rust-lang/rust/blob/7bd81ee1902c049691d0a1f03be5558bee51d100/compiler/rustc_codegen_ssa/src/back/linker.rs#L319

Test: m libhalf serde_derive
Bug: 291164566
Change-Id: Iecd6c2532fa31c9476834f49b109de98cbd2dccf
diff --git a/rust/builder.go b/rust/builder.go
index fbceecc..b1f049d 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -45,9 +45,9 @@
 		"rustcFlags", "libFlags", "envVars")
 	rustLink = pctx.AndroidStaticRule("rustLink",
 		blueprint.RuleParams{
-			Command: "${config.RustLinker} -o $out ${crtBegin} ${config.RustLinkerArgs} @$in ${linkFlags} ${crtEnd}",
+			Command: "${config.RustLinker} -o $out ${crtBegin} ${earlyLinkFlags} @$in ${linkFlags} ${crtEnd}",
 		},
-		"linkFlags", "crtBegin", "crtEnd")
+		"earlyLinkFlags", "linkFlags", "crtBegin", "crtEnd")
 
 	_       = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
 	rustdoc = pctx.AndroidStaticRule("rustdoc",
@@ -244,6 +244,10 @@
 
 	envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar")
 
+	if ctx.Darwin() {
+		envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
+	}
+
 	return envVars
 }
 
@@ -254,6 +258,7 @@
 	var implicits, linkImplicits, linkOrderOnly android.Paths
 	var output buildOutput
 	var rustcFlags, linkFlags []string
+	var earlyLinkFlags string
 
 	output.outputFile = outputFile
 	crateName := ctx.RustModule().CrateName()
@@ -292,6 +297,10 @@
 	}
 
 	// Collect linker flags
+	if !ctx.Darwin() {
+		earlyLinkFlags = "-Wl,--as-needed"
+	}
+
 	linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
 	linkFlags = append(linkFlags, flags.LinkFlags...)
 
@@ -391,9 +400,10 @@
 			Implicits:   linkImplicits,
 			OrderOnly:   linkOrderOnly,
 			Args: map[string]string{
-				"linkFlags": strings.Join(linkFlags, " "),
-				"crtBegin":  strings.Join(deps.CrtBegin.Strings(), " "),
-				"crtEnd":    strings.Join(deps.CrtEnd.Strings(), " "),
+				"earlyLinkFlags": earlyLinkFlags,
+				"linkFlags":      strings.Join(linkFlags, " "),
+				"crtBegin":       strings.Join(deps.CrtBegin.Strings(), " "),
+				"crtEnd":         strings.Join(deps.CrtEnd.Strings(), " "),
 			},
 		})
 	}
diff --git a/rust/config/global.go b/rust/config/global.go
index c39341e..86eb2d1 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -102,7 +102,6 @@
 
 	pctx.ImportAs("cc_config", "android/soong/cc/config")
 	pctx.StaticVariable("RustLinker", "${cc_config.ClangBin}/clang++")
-	pctx.StaticVariable("RustLinkerArgs", "-Wl,--as-needed")
 
 	pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
 
diff --git a/scripts/mkcratersp.py b/scripts/mkcratersp.py
index 86b4aa3..6ef01eb 100755
--- a/scripts/mkcratersp.py
+++ b/scripts/mkcratersp.py
@@ -48,6 +48,8 @@
     linkdirs.append(sys.argv[i+1])
   if arg.startswith('-l') or arg == '-shared':
     libs.append(arg)
+  if os.getenv('ANDROID_RUST_DARWIN') and (arg == '-dylib' or arg == '-dynamiclib'):
+    libs.append(arg)
   if arg.startswith('-Wl,--version-script='):
     version_script = arg[21:]
   if arg[0] == '-':
@@ -64,9 +66,13 @@
 create_archive(f'{out}.a', [], temp_archives)
 
 with open(out, 'w') as f:
-  print(f'-Wl,--whole-archive', file=f)
-  print(f'{out}.whole.a', file=f)
-  print(f'-Wl,--no-whole-archive', file=f)
+  if os.getenv("ANDROID_RUST_DARWIN"):
+    print(f'-force_load', file=f)
+    print(f'{out}.whole.a', file=f)
+  else:
+    print(f'-Wl,--whole-archive', file=f)
+    print(f'{out}.whole.a', file=f)
+    print(f'-Wl,--no-whole-archive', file=f)
   print(f'{out}.a', file=f)
   for a in archives:
     print(a, file=f)