Allow genrules to depend on tools with symlinks

Symlink PackagingSpecs don't have a sourcePath, so it crashes soong
if you try to add a tool with symlinks to a genrule. Make RuleBuilder
ignore symlink packaging specs.

We could make RuleBuilder add them to the sandbox later if needed.

Bug: 395988167
Test: go test
Change-Id: I4dd2bdec6ff6e94f5014889e4a9378ae4c20f9e3
diff --git a/android/rule_builder.go b/android/rule_builder.go
index ea6aaa4..01fe6d8 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -660,12 +660,17 @@
 			}
 			for _, c := range r.commands {
 				for _, tool := range c.packagedTools {
-					command.CopyBefore = append(command.CopyBefore, &sbox_proto.Copy{
-						From:       proto.String(tool.srcPath.String()),
-						To:         proto.String(sboxPathForPackagedToolRel(tool)),
-						Executable: proto.Bool(tool.executable),
-					})
-					tools = append(tools, tool.srcPath)
+					if tool.srcPath != nil {
+						command.CopyBefore = append(command.CopyBefore, &sbox_proto.Copy{
+							From:       proto.String(tool.srcPath.String()),
+							To:         proto.String(sboxPathForPackagedToolRel(tool)),
+							Executable: proto.Bool(tool.executable),
+						})
+						tools = append(tools, tool.srcPath)
+					} else if tool.SymlinkTarget() == "" {
+						// We ignore symlinks for now, could be added later if needed
+						panic("Expected tool packagingSpec to either be a file or symlink")
+					}
 				}
 			}
 		}
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index 438eb98..4e700a2 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -17,6 +17,7 @@
 import (
 	"reflect"
 	"slices"
+	"strings"
 	"testing"
 
 	"android/soong/android"
@@ -254,3 +255,42 @@
 		gen_64bit,
 	)
 }
+
+// Test that a genrule can depend on a tool with symlinks. The symlinks are ignored, but
+// at least it doesn't cause errors.
+func TestGenruleToolWithSymlinks(t *testing.T) {
+	bp := `
+	genrule {
+		name: "gen",
+		tools: ["tool_with_symlinks"],
+		cmd: "$(location tool_with_symlinks) $(in) $(out)",
+		out: ["out"],
+	}
+
+	cc_binary_host {
+		name: "tool_with_symlinks",
+		symlinks: ["symlink1", "symlink2"],
+	}
+	`
+	ctx := PrepareForIntegrationTestWithCc.
+		ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
+		RunTestWithBp(t, bp)
+	gen := ctx.ModuleForTests(t, "gen", "").Output("out")
+	toolFound := false
+	symlinkFound := false
+	for _, dep := range gen.RuleParams.CommandDeps {
+		if strings.HasSuffix(dep, "/tool_with_symlinks") {
+			toolFound = true
+		}
+		if strings.HasSuffix(dep, "/symlink1") || strings.HasSuffix(dep, "/symlink2") {
+			symlinkFound = true
+		}
+	}
+	if !toolFound {
+		t.Errorf("Tool not found")
+	}
+	// We may want to change genrules to include symlinks later
+	if symlinkFound {
+		t.Errorf("Symlinks found")
+	}
+}