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

Commit e3487c88 authored by Lukacs T. Berki's avatar Lukacs T. Berki
Browse files

Add a test for correctness of C++ compilation.

This required the following:

- Adding Platform_base_sdk_extension_version to default soong.variables
- Teaching the symlink tree creation code to understand symlinks
- Making finder.go follow symlinks when requested

Adding yet another knob is unfortunate, but I can't allow that
unconditionally because the Android code base contains a number of
symlinks giving rise to infinite directory trees because they point back
to their parent and this seemed preferable to adding complicated logic
like "follow symlink but if only its fully resolved version does not
point under the source tree".

I could be convinced about the latter, though.

Test: Presubmits.
Change-Id: I453f6b7e5334771f5832c700db00f9d24ed1d82f
parent a704eb14
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -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),
+28 −4
Original line number Diff line number Diff line
@@ -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
@@ -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)
@@ -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)
@@ -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",
+12 −3
Original line number Diff line number Diff line
@@ -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

@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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"},
@@ -121,6 +122,7 @@ func runTestWithSuffixes(t *testing.T, existentPaths []string, expectedMatches [
		CacheParams{
			"/cwd",
			[]string{root},
			false,
			nil,
			nil,
			[]string{"findme.txt", "skipme.txt"},
+54 −0
Original line number Diff line number Diff line
@@ -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