Create a synthetic Bazel workspace.

It's under out/soong/workspace and is a symlink forest that merges BUILD
files generated by bp2build and the source tree.

bazel-* symlinks and $OUTDIR are currently ignored.

Test: Presubmits.
Change-Id: If14df23bd0f6a6f2d7d1140f95213f2aee66d652
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index c9cab13..5bccf58 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -396,6 +396,37 @@
 		ninjaDeps = append(ninjaDeps, globPath.FileListFile(configuration.BuildDir()))
 	}
 
+	// Run the code-generation phase to convert BazelTargetModules to BUILD files
+	// and print conversion metrics to the user.
+	codegenContext := bp2build.NewCodegenContext(configuration, *bp2buildCtx, bp2build.Bp2Build)
+	metrics := bp2build.Codegen(codegenContext)
+
+	generatedRoot := shared.JoinPath(configuration.BuildDir(), "bp2build")
+	workspaceRoot := shared.JoinPath(configuration.BuildDir(), "workspace")
+
+	excludes := []string{
+		"bazel-bin",
+		"bazel-genfiles",
+		"bazel-out",
+		"bazel-testlogs",
+		"bazel-" + filepath.Base(topDir),
+	}
+
+	if bootstrap.CmdlineArgs.NinjaBuildDir[0] != '/' {
+		excludes = append(excludes, bootstrap.CmdlineArgs.NinjaBuildDir)
+	}
+
+	symlinkForestDeps := bp2build.PlantSymlinkForest(
+		topDir, workspaceRoot, generatedRoot, configuration.SrcDir(), excludes)
+
+	// Only report metrics when in bp2build mode. The metrics aren't relevant
+	// for queryview, since that's a total repo-wide conversion and there's a
+	// 1:1 mapping for each module.
+	metrics.Print()
+
+	ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
+	ninjaDeps = append(ninjaDeps, symlinkForestDeps...)
+
 	depFile := bp2buildMarker + ".d"
 	err = deptools.WriteDepFile(shared.JoinPath(topDir, depFile), bp2buildMarker, ninjaDeps)
 	if err != nil {
@@ -403,17 +434,6 @@
 		os.Exit(1)
 	}
 
-	// Run the code-generation phase to convert BazelTargetModules to BUILD files
-	// and print conversion metrics to the user.
-	codegenContext := bp2build.NewCodegenContext(configuration, *bp2buildCtx, bp2build.Bp2Build)
-	metrics := bp2build.Codegen(codegenContext)
-
-	// Only report metrics when in bp2build mode. The metrics aren't relevant
-	// for queryview, since that's a total repo-wide conversion and there's a
-	// 1:1 mapping for each module.
-	metrics.Print()
-
-	extraNinjaDeps = append(extraNinjaDeps, codegenContext.AdditionalNinjaDeps()...)
 	if bp2buildMarker != "" {
 		touch(shared.JoinPath(topDir, bp2buildMarker))
 	} else {