c9508aac4c
There are a number of instances where we are exporting information from soong to bazel via soong_injection. This could be more bazel-centric if the information was instead held in bzl files, and both bazel and soong read it from there. Add a starlark package that will run //build/bazel/constants_exported_to_soong.bzl at initialization time, and then results can be retreived with GetStarlarkValue. Since changes to the starlark files mean that soong has to rerun, add them as ninja deps. Unfortunately, the starlark code has to be run at runtime rather than pregenerating their results, because tests run from intellij wouldn't go through any pregeneration steps. This means that starlark is run multiple times during the build, once per test package and once per primary builder invocation. (currently 3, could be reduced to 2 if we made the symlink forest generation into its own standalone tool) The starlark code we have so far in this cl is very fast, roughly half a millisecond, so it's not a big deal for now, but something to keep an eye on as we add more starlark constants. Bug: 279095899 Test: go test Change-Id: I1e7ca1df1d8d67333cbfc46e8396e229820e4476
385 lines
10 KiB
Bash
Executable file
385 lines
10 KiB
Bash
Executable file
#!/bin/bash -eu
|
|
|
|
set -o pipefail
|
|
|
|
# Test that bp2build and Bazel can play nicely together
|
|
|
|
source "$(dirname "$0")/lib.sh"
|
|
|
|
readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
|
|
|
|
function test_bp2build_null_build {
|
|
setup
|
|
run_soong bp2build
|
|
local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
run_soong bp2build
|
|
local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
if [[ "$output_mtime1" != "$output_mtime2" ]]; then
|
|
fail "Output bp2build marker file changed on null build"
|
|
fi
|
|
}
|
|
|
|
# Tests that, if bp2build reruns due to a blueprint file changing, that
|
|
# BUILD files whose contents are unchanged are not regenerated.
|
|
function test_bp2build_unchanged {
|
|
setup
|
|
|
|
mkdir -p pkg
|
|
touch pkg/x.txt
|
|
cat > pkg/Android.bp <<'EOF'
|
|
filegroup {
|
|
name: "x",
|
|
srcs: ["x.txt"],
|
|
bazel_module: {bp2build_available: true},
|
|
}
|
|
EOF
|
|
|
|
run_soong bp2build
|
|
local -r buildfile_mtime1=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
|
|
local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
# Force bp2build to rerun by updating the timestamp of a blueprint file.
|
|
touch pkg/Android.bp
|
|
|
|
run_soong bp2build
|
|
local -r buildfile_mtime2=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
|
|
local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
if [[ "$marker_mtime1" == "$marker_mtime2" ]]; then
|
|
fail "Expected bp2build marker file to change"
|
|
fi
|
|
if [[ "$buildfile_mtime1" != "$buildfile_mtime2" ]]; then
|
|
fail "BUILD.bazel was updated even though contents are same"
|
|
fi
|
|
|
|
# Force bp2build to rerun by updating the timestamp of the constants_exported_to_soong.bzl file.
|
|
touch build/bazel/constants_exported_to_soong.bzl
|
|
|
|
run_soong bp2build
|
|
local -r buildfile_mtime3=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
|
|
local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
if [[ "$marker_mtime2" == "$marker_mtime3" ]]; then
|
|
fail "Expected bp2build marker file to change"
|
|
fi
|
|
if [[ "$buildfile_mtime2" != "$buildfile_mtime3" ]]; then
|
|
fail "BUILD.bazel was updated even though contents are same"
|
|
fi
|
|
}
|
|
|
|
# Tests that blueprint files that are deleted are not present when the
|
|
# bp2build tree is regenerated.
|
|
function test_bp2build_deleted_blueprint {
|
|
setup
|
|
|
|
mkdir -p pkg
|
|
touch pkg/x.txt
|
|
cat > pkg/Android.bp <<'EOF'
|
|
filegroup {
|
|
name: "x",
|
|
srcs: ["x.txt"],
|
|
bazel_module: {bp2build_available: true},
|
|
}
|
|
EOF
|
|
|
|
run_soong bp2build
|
|
if [[ ! -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
|
|
fail "Expected pkg/BUILD.bazel to be generated"
|
|
fi
|
|
|
|
rm pkg/Android.bp
|
|
|
|
run_soong bp2build
|
|
if [[ -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
|
|
fail "Expected pkg/BUILD.bazel to be deleted"
|
|
fi
|
|
}
|
|
|
|
function test_bp2build_null_build_with_globs {
|
|
setup
|
|
|
|
mkdir -p foo/bar
|
|
cat > foo/bar/Android.bp <<'EOF'
|
|
filegroup {
|
|
name: "globs",
|
|
srcs: ["*.txt"],
|
|
}
|
|
EOF
|
|
touch foo/bar/a.txt foo/bar/b.txt
|
|
|
|
run_soong bp2build
|
|
local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
run_soong bp2build
|
|
local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
|
|
|
|
if [[ "$output_mtime1" != "$output_mtime2" ]]; then
|
|
fail "Output bp2build marker file changed on null build"
|
|
fi
|
|
}
|
|
|
|
function test_different_relative_outdir {
|
|
setup
|
|
|
|
mkdir -p a
|
|
touch a/g.txt
|
|
cat > a/Android.bp <<'EOF'
|
|
filegroup {
|
|
name: "g",
|
|
srcs: ["g.txt"],
|
|
bazel_module: {bp2build_available: true},
|
|
}
|
|
EOF
|
|
|
|
# A directory under $MOCK_TOP
|
|
outdir=out2
|
|
trap "rm -rf $outdir" EXIT
|
|
# Modify OUT_DIR in a subshell so it doesn't affect the top level one.
|
|
(export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
|
|
}
|
|
|
|
function test_different_absolute_outdir {
|
|
setup
|
|
|
|
mkdir -p a
|
|
touch a/g.txt
|
|
cat > a/Android.bp <<'EOF'
|
|
filegroup {
|
|
name: "g",
|
|
srcs: ["g.txt"],
|
|
bazel_module: {bp2build_available: true},
|
|
}
|
|
EOF
|
|
|
|
# A directory under /tmp/...
|
|
outdir=$(mktemp -t -d st.XXXXX)
|
|
trap 'rm -rf $outdir' EXIT
|
|
# Modify OUT_DIR in a subshell so it doesn't affect the top level one.
|
|
(export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
|
|
}
|
|
|
|
function _bp2build_generates_all_buildfiles {
|
|
setup
|
|
|
|
mkdir -p foo/convertible_soong_module
|
|
cat > foo/convertible_soong_module/Android.bp <<'EOF'
|
|
genrule {
|
|
name: "the_answer",
|
|
cmd: "echo '42' > $(out)",
|
|
out: [
|
|
"the_answer.txt",
|
|
],
|
|
bazel_module: {
|
|
bp2build_available: true,
|
|
},
|
|
}
|
|
EOF
|
|
|
|
mkdir -p foo/unconvertible_soong_module
|
|
cat > foo/unconvertible_soong_module/Android.bp <<'EOF'
|
|
genrule {
|
|
name: "not_the_answer",
|
|
cmd: "echo '43' > $(out)",
|
|
out: [
|
|
"not_the_answer.txt",
|
|
],
|
|
bazel_module: {
|
|
bp2build_available: false,
|
|
},
|
|
}
|
|
EOF
|
|
|
|
run_soong bp2build
|
|
|
|
if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
|
|
fail "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
|
|
fi
|
|
|
|
if [[ ! -f "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
|
|
fail "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
|
|
fi
|
|
|
|
if ! grep "the_answer" "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
|
|
fail "missing BUILD target the_answer in convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
|
|
fi
|
|
|
|
if grep "not_the_answer" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
|
|
fail "found unexpected BUILD target not_the_answer in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
|
|
fi
|
|
|
|
if ! grep "filegroup" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
|
|
fail "missing filegroup in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
|
|
fi
|
|
|
|
# NOTE: We don't actually use the extra BUILD file for anything here
|
|
run_bazel build --config=android --config=bp2build --config=ci //foo/...
|
|
|
|
local -r the_answer_file="$(find -L bazel-out -name the_answer.txt)"
|
|
if [[ ! -f "${the_answer_file}" ]]; then
|
|
fail "Expected the_answer.txt to be generated, but was missing"
|
|
fi
|
|
if ! grep 42 "${the_answer_file}"; then
|
|
fail "Expected to find 42 in '${the_answer_file}'"
|
|
fi
|
|
}
|
|
|
|
function test_bp2build_generates_all_buildfiles {
|
|
_save_trap=$(trap -p EXIT)
|
|
trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
|
|
_bp2build_generates_all_buildfiles
|
|
eval "${_save_trap}"
|
|
}
|
|
|
|
function test_bp2build_symlinks_files {
|
|
setup
|
|
mkdir -p foo
|
|
touch foo/BLANK1
|
|
touch foo/BLANK2
|
|
touch foo/F2D
|
|
touch foo/BUILD
|
|
|
|
run_soong bp2build
|
|
|
|
if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
|
|
fail "./out/soong/workspace/foo/BUILD should be omitted"
|
|
fi
|
|
for file in BLANK1 BLANK2 F2D
|
|
do
|
|
if [[ ! -L "./out/soong/workspace/foo/$file" ]]; then
|
|
fail "./out/soong/workspace/foo/$file should exist"
|
|
fi
|
|
done
|
|
local -r BLANK1_BEFORE=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
|
|
|
|
rm foo/BLANK2
|
|
rm foo/F2D
|
|
mkdir foo/F2D
|
|
touch foo/F2D/BUILD
|
|
|
|
run_soong bp2build
|
|
|
|
if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
|
|
fail "./out/soong/workspace/foo/BUILD should be omitted"
|
|
fi
|
|
local -r BLANK1_AFTER=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
|
|
if [[ "$BLANK1_AFTER" != "$BLANK1_BEFORE" ]]; then
|
|
fail "./out/soong/workspace/foo/BLANK1 should be untouched"
|
|
fi
|
|
if [[ -e "./out/soong/workspace/foo/BLANK2" ]]; then
|
|
fail "./out/soong/workspace/foo/BLANK2 should be removed"
|
|
fi
|
|
if [[ -L "./out/soong/workspace/foo/F2D" ]] || [[ ! -d "./out/soong/workspace/foo/F2D" ]]; then
|
|
fail "./out/soong/workspace/foo/F2D should be a dir"
|
|
fi
|
|
}
|
|
|
|
function test_cc_correctness {
|
|
setup
|
|
|
|
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 --config=android --config=bp2build --config=ci //a:qq
|
|
local -r output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
|
|
|
|
run_bazel build --config=android --config=bp2build --config=ci //a:qq
|
|
local -r 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 --config=android --config=bp2build --config=ci //a:qq
|
|
local -r 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
|
|
}
|
|
|
|
# Regression test for the following failure during symlink forest creation:
|
|
#
|
|
# Cannot stat '/tmp/st.rr054/foo/bar/unresolved_symlink': stat /tmp/st.rr054/foo/bar/unresolved_symlink: no such file or directory
|
|
#
|
|
function test_bp2build_null_build_with_unresolved_symlink_in_source() {
|
|
setup
|
|
|
|
mkdir -p foo/bar
|
|
ln -s /tmp/non-existent foo/bar/unresolved_symlink
|
|
cat > foo/bar/Android.bp <<'EOF'
|
|
filegroup {
|
|
name: "fg",
|
|
srcs: ["unresolved_symlink/non-existent-file.txt"],
|
|
}
|
|
EOF
|
|
|
|
run_soong bp2build
|
|
|
|
dest=$(readlink -f out/soong/workspace/foo/bar/unresolved_symlink)
|
|
if [[ "$dest" != "/tmp/non-existent" ]]; then
|
|
fail "expected to plant an unresolved symlink out/soong/workspace/foo/bar/unresolved_symlink that resolves to /tmp/non-existent"
|
|
fi
|
|
}
|
|
|
|
# Smoke test to verify api_bp2build worksapce does not contain any errors
|
|
function test_api_bp2build_empty_build() {
|
|
setup
|
|
run_soong api_bp2build
|
|
run_bazel build --config=android --config=api_bp2build //:empty
|
|
}
|
|
|
|
# Verify that an *_api_contribution target can refer to an api file from
|
|
# another Bazel package.
|
|
function test_api_export_from_another_bazel_package() {
|
|
setup
|
|
# Parent dir Android.bp
|
|
mkdir -p foo
|
|
cat > foo/Android.bp << 'EOF'
|
|
cc_library {
|
|
name: "libfoo",
|
|
stubs: {
|
|
symbol_file: "api/libfoo.map.txt",
|
|
},
|
|
}
|
|
EOF
|
|
# Child dir Android.bp
|
|
mkdir -p foo/api
|
|
cat > foo/api/Android.bp << 'EOF'
|
|
package{}
|
|
EOF
|
|
touch foo/api/libfoo.map.txt
|
|
# Run test
|
|
run_soong api_bp2build
|
|
run_bazel build --config=android --config=api_bp2build //foo:libfoo.contribution
|
|
}
|
|
|
|
scan_and_run_tests
|