Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f4f5217 authored by Cole Faust's avatar Cole Faust
Browse files

Fix issue merging bp2build files with handcrafted ones

It was possible for the merged content to end up back in the bp2build
generated file because there was a symlink from the symlink forest to
the bp2build generated file.

Remove the symlink if it exists.

Bug: 276349152
Test: m bp2build, add a handcrafted file in the same folder as a Android.bp file, m bp2build again, check that the symlink forest version is not a symlink
Change-Id: Id64aa3addebcf0c6b1728389f21ae246796aaf8d
parent 28ba8066
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import (
	"sync/atomic"

	"android/soong/shared"

	"github.com/google/blueprint/pathtools"
)

@@ -123,6 +124,34 @@ func mergeBuildFiles(output string, srcBuildFile string, generatedBuildFile stri
	}
	newContents = append(newContents, srcBuildFileContent...)

	// Say you run bp2build 4 times:
	// - The first time there's only an Android.bp file. bp2build will convert it to a build file
	//   under out/soong/bp2build, then symlink from the forest to that generated file
	// - Then you add a handcrafted BUILD file in the same directory. bp2build will merge this with
	//   the generated one, and write the result to the output file in the forest. But the output
	//   file was a symlink to out/soong/bp2build from the previous step! So we erroneously update
	//   the file in out/soong/bp2build instead. So far this doesn't cause any problems...
	// - You run a 3rd bp2build with no relevant changes. Everything continues to work.
	// - You then add a comment to the handcrafted BUILD file. This causes a merge with the
	//   generated file again. But since we wrote to the generated file in step 2, the generated
	//   file has an old copy of the handcrafted file in it! This probably causes duplicate bazel
	//   targets.
	// To solve this, if we see that the output file is a symlink from a previous build, remove it.
	stat, err := os.Lstat(output)
	if err != nil && !os.IsNotExist(err) {
		return err
	} else if err == nil {
		if stat.Mode()&os.ModeSymlink == os.ModeSymlink {
			if verbose {
				fmt.Fprintf(os.Stderr, "Removing symlink so that we can replace it with a merged file: %s\n", output)
			}
			err = os.Remove(output)
			if err != nil {
				return err
			}
		}
	}

	return pathtools.WriteFileIfChanged(output, newContents, 0666)
}