Loading android/variable.go +7 −6 Original line number Diff line number Diff line Loading @@ -464,6 +464,7 @@ func (v *productVariables) SetDefaultConfig() { BuildNumberFile: stringPtr("build_number.txt"), Platform_version_name: stringPtr("S"), Platform_base_sdk_extension_version: intPtr(30), Platform_sdk_version: intPtr(30), Platform_sdk_codename: stringPtr("S"), Platform_sdk_final: boolPtr(false), Loading bp2build/symlink_forest.go +28 −4 Original line number Diff line number Diff line Loading @@ -90,6 +90,20 @@ func symlinkIntoForest(topdir, dst, src string) { } } func isDir(path string, fi os.FileInfo) bool { if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink { return fi.IsDir() } fi2, err := os.Stat(path) if err != nil { fmt.Fprintf(os.Stderr, "Cannot stat '%s': %s\n", path, err) os.Exit(1) } return fi2.IsDir() } // Recursively plants a symlink forest at forestDir. The symlink tree will // contain every file in buildFilesDir and srcDir excluding the files in // exclude. Collects every directory encountered during the traversal of srcDir Loading Loading @@ -145,8 +159,18 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir continue } sDir := false bDir := false if sExists { sDir = isDir(shared.JoinPath(topdir, srcChild), srcChildEntry) } if bExists { bDir = isDir(shared.JoinPath(topdir, buildFilesChild), buildFilesChildEntry) } if !sExists { if buildFilesChildEntry.IsDir() && excludeChild != nil { if bDir && excludeChild != nil { // Not in the source tree, but we have to exclude something from under // this subtree, so descend plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay) Loading @@ -155,7 +179,7 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir symlinkIntoForest(topdir, forestChild, buildFilesChild) } } else if !bExists { if srcChildEntry.IsDir() && excludeChild != nil { if sDir && excludeChild != nil { // Not in the build file tree, but we have to exclude something from // under this subtree, so descend plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay) Loading @@ -163,10 +187,10 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir // Not in the build file tree, symlink source tree, carry on symlinkIntoForest(topdir, forestChild, srcChild) } } else if srcChildEntry.IsDir() && buildFilesChildEntry.IsDir() { } else if sDir && bDir { // Both are directories. Descend. plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay) } else if !srcChildEntry.IsDir() && !buildFilesChildEntry.IsDir() { } else if !sDir && !bDir { // Neither is a directory. Prioritize BUILD files generated by bp2build // over any BUILD file imported into external/. fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n", Loading finder/finder.go +12 −3 Original line number Diff line number Diff line Loading @@ -94,6 +94,10 @@ type CacheParams struct { // RootDirs are the root directories used to initiate the search RootDirs []string // Whether symlinks are followed. If set, symlinks back to their own parent // directory don't work. FollowSymlinks bool // ExcludeDirs are directory names that if encountered are removed from the search ExcludeDirs []string Loading Loading @@ -1415,9 +1419,14 @@ func (f *Finder) listDirSync(dir *pathMap) { // If stat fails this is probably a broken or dangling symlink, treat it as a file. subfiles = append(subfiles, child.Name()) } else if childStat.IsDir() { // Skip symlink dirs. // We don't have to support symlink dirs because // that would cause duplicates. // Skip symlink dirs if not requested otherwise. Android has a number // of symlinks creating infinite source trees which would otherwise get // us in an infinite loop. // TODO(b/197349722): Revisit this once symlink loops are banned in the // source tree. if f.cacheMetadata.Config.FollowSymlinks { subdirs = append(subdirs, child.Name()) } } else { // We do have to support symlink files because the link name might be // different than the target name Loading finder/finder_test.go +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ func runSimpleTest(t *testing.T, existentPaths []string, expectedMatches []strin CacheParams{ "/cwd", []string{root}, false, nil, nil, []string{"findme.txt", "skipme.txt"}, Loading Loading @@ -121,6 +122,7 @@ func runTestWithSuffixes(t *testing.T, existentPaths []string, expectedMatches [ CacheParams{ "/cwd", []string{root}, false, nil, nil, []string{"findme.txt", "skipme.txt"}, Loading tests/bp2build_bazel_test.sh +54 −0 Original line number Diff line number Diff line Loading @@ -115,3 +115,57 @@ EOF } test_bp2build_generates_all_buildfiles function test_cc_correctness { setup create_mock_bazel mkdir -p a cat > a/Android.bp <<EOF cc_object { name: "qq", srcs: ["qq.cc"], bazel_module: { bp2build_available: true, }, stl: "none", system_shared_libs: [], } EOF cat > a/qq.cc <<EOF #include "qq.h" int qq() { return QQ; } EOF cat > a/qq.h <<EOF #define QQ 1 EOF run_soong bp2build run_bazel build --package_path=out/soong/workspace //a:qq local output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o) run_bazel build --package_path=out/soong/workspace //a:qq local output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o) if [[ "$output_mtime1" != "$output_mtime2" ]]; then fail "output changed on null build" fi cat > a/qq.h <<EOF #define QQ 2 EOF run_bazel build --package_path=out/soong/workspace //a:qq local output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o) if [[ "$output_mtime1" == "$output_mtime3" ]]; then fail "output not changed when included header changed" fi } test_cc_correctness Loading
android/variable.go +7 −6 Original line number Diff line number Diff line Loading @@ -464,6 +464,7 @@ func (v *productVariables) SetDefaultConfig() { BuildNumberFile: stringPtr("build_number.txt"), Platform_version_name: stringPtr("S"), Platform_base_sdk_extension_version: intPtr(30), Platform_sdk_version: intPtr(30), Platform_sdk_codename: stringPtr("S"), Platform_sdk_final: boolPtr(false), Loading
bp2build/symlink_forest.go +28 −4 Original line number Diff line number Diff line Loading @@ -90,6 +90,20 @@ func symlinkIntoForest(topdir, dst, src string) { } } func isDir(path string, fi os.FileInfo) bool { if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink { return fi.IsDir() } fi2, err := os.Stat(path) if err != nil { fmt.Fprintf(os.Stderr, "Cannot stat '%s': %s\n", path, err) os.Exit(1) } return fi2.IsDir() } // Recursively plants a symlink forest at forestDir. The symlink tree will // contain every file in buildFilesDir and srcDir excluding the files in // exclude. Collects every directory encountered during the traversal of srcDir Loading Loading @@ -145,8 +159,18 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir continue } sDir := false bDir := false if sExists { sDir = isDir(shared.JoinPath(topdir, srcChild), srcChildEntry) } if bExists { bDir = isDir(shared.JoinPath(topdir, buildFilesChild), buildFilesChildEntry) } if !sExists { if buildFilesChildEntry.IsDir() && excludeChild != nil { if bDir && excludeChild != nil { // Not in the source tree, but we have to exclude something from under // this subtree, so descend plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay) Loading @@ -155,7 +179,7 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir symlinkIntoForest(topdir, forestChild, buildFilesChild) } } else if !bExists { if srcChildEntry.IsDir() && excludeChild != nil { if sDir && excludeChild != nil { // Not in the build file tree, but we have to exclude something from // under this subtree, so descend plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay) Loading @@ -163,10 +187,10 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir // Not in the build file tree, symlink source tree, carry on symlinkIntoForest(topdir, forestChild, srcChild) } } else if srcChildEntry.IsDir() && buildFilesChildEntry.IsDir() { } else if sDir && bDir { // Both are directories. Descend. plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay) } else if !srcChildEntry.IsDir() && !buildFilesChildEntry.IsDir() { } else if !sDir && !bDir { // Neither is a directory. Prioritize BUILD files generated by bp2build // over any BUILD file imported into external/. fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n", Loading
finder/finder.go +12 −3 Original line number Diff line number Diff line Loading @@ -94,6 +94,10 @@ type CacheParams struct { // RootDirs are the root directories used to initiate the search RootDirs []string // Whether symlinks are followed. If set, symlinks back to their own parent // directory don't work. FollowSymlinks bool // ExcludeDirs are directory names that if encountered are removed from the search ExcludeDirs []string Loading Loading @@ -1415,9 +1419,14 @@ func (f *Finder) listDirSync(dir *pathMap) { // If stat fails this is probably a broken or dangling symlink, treat it as a file. subfiles = append(subfiles, child.Name()) } else if childStat.IsDir() { // Skip symlink dirs. // We don't have to support symlink dirs because // that would cause duplicates. // Skip symlink dirs if not requested otherwise. Android has a number // of symlinks creating infinite source trees which would otherwise get // us in an infinite loop. // TODO(b/197349722): Revisit this once symlink loops are banned in the // source tree. if f.cacheMetadata.Config.FollowSymlinks { subdirs = append(subdirs, child.Name()) } } else { // We do have to support symlink files because the link name might be // different than the target name Loading
finder/finder_test.go +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ func runSimpleTest(t *testing.T, existentPaths []string, expectedMatches []strin CacheParams{ "/cwd", []string{root}, false, nil, nil, []string{"findme.txt", "skipme.txt"}, Loading Loading @@ -121,6 +122,7 @@ func runTestWithSuffixes(t *testing.T, existentPaths []string, expectedMatches [ CacheParams{ "/cwd", []string{root}, false, nil, nil, []string{"findme.txt", "skipme.txt"}, Loading
tests/bp2build_bazel_test.sh +54 −0 Original line number Diff line number Diff line Loading @@ -115,3 +115,57 @@ EOF } test_bp2build_generates_all_buildfiles function test_cc_correctness { setup create_mock_bazel mkdir -p a cat > a/Android.bp <<EOF cc_object { name: "qq", srcs: ["qq.cc"], bazel_module: { bp2build_available: true, }, stl: "none", system_shared_libs: [], } EOF cat > a/qq.cc <<EOF #include "qq.h" int qq() { return QQ; } EOF cat > a/qq.h <<EOF #define QQ 1 EOF run_soong bp2build run_bazel build --package_path=out/soong/workspace //a:qq local output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o) run_bazel build --package_path=out/soong/workspace //a:qq local output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o) if [[ "$output_mtime1" != "$output_mtime2" ]]; then fail "output changed on null build" fi cat > a/qq.h <<EOF #define QQ 2 EOF run_bazel build --package_path=out/soong/workspace //a:qq local output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o) if [[ "$output_mtime1" == "$output_mtime3" ]]; then fail "output not changed when included header changed" fi } test_cc_correctness