diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh index b37a7f82a..5853a7b00 100755 --- a/tests/bootstrap_test.sh +++ b/tests/bootstrap_test.sh @@ -522,7 +522,7 @@ EOF function test_bp2build_smoke { setup - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build [[ -e out/soong/.bootstrap/bp2build_workspace_marker ]] || fail "bp2build marker file not created" [[ -e out/soong/workspace ]] || fail "Bazel workspace not created" } @@ -531,7 +531,7 @@ function test_bp2build_generates_marker_file { setup create_mock_bazel - run_bp2build + run_soong bp2build if [[ ! -f "./out/soong/.bootstrap/bp2build_workspace_marker" ]]; then fail "Marker file was not generated" @@ -551,7 +551,7 @@ filegroup { } EOF - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build [[ -e out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created" [[ -L out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked" @@ -565,7 +565,7 @@ filegroup { } EOF - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build [[ -e out/soong/bp2build/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created" [[ -L out/soong/workspace/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked" } @@ -573,10 +573,10 @@ EOF function test_bp2build_null_build { setup - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build local mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build local mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) if [[ "$mtime1" != "$mtime2" ]]; then @@ -597,18 +597,35 @@ filegroup { } EOF - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build grep -q a1.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a1.txt not in ${GENERATED_BUILD_FILE_NAME} file" touch a/a2.txt - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build grep -q a2.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a2.txt not in ${GENERATED_BUILD_FILE_NAME} file" } +function test_multiple_soong_build_modes() { + setup + run_soong json-module-graph bp2build nothing + if [[ ! -f "out/soong/.bootstrap/bp2build_workspace_marker" ]]; then + fail "bp2build marker file was not generated" + fi + + + if [[ ! -f "out/soong/module-graph.json" ]]; then + fail "JSON file was not created" + fi + + if [[ ! -f "out/soong/build.ninja" ]]; then + fail "Main build.ninja file was not created" + fi +} + function test_dump_json_module_graph() { setup - GENERATE_JSON_MODULE_GRAPH=1 run_soong - if [[ ! -r "out/soong//module-graph.json" ]]; then + run_soong json-module-graph + if [[ ! -r "out/soong/module-graph.json" ]]; then fail "JSON file was not created" fi } @@ -619,7 +636,7 @@ function test_json_module_graph_back_and_forth_null_build() { run_soong local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja) - GENERATE_JSON_MODULE_GRAPH=1 run_soong + run_soong json-module-graph local json_mtime1=$(stat -c "%y" out/soong/module-graph.json) run_soong @@ -628,7 +645,7 @@ function test_json_module_graph_back_and_forth_null_build() { fail "Output Ninja file changed after writing JSON module graph" fi - GENERATE_JSON_MODULE_GRAPH=1 run_soong + run_soong json-module-graph local json_mtime2=$(stat -c "%y" out/soong/module-graph.json) if [[ "$json_mtime1" != "$json_mtime2" ]]; then fail "JSON module graph file changed after writing Ninja file" @@ -651,7 +668,7 @@ filegroup { } EOF - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build [[ -e out/soong/workspace ]] || fail "Bazel workspace not created" [[ -d out/soong/workspace/a/b ]] || fail "module directory not a directory" [[ -L "out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked" @@ -675,10 +692,10 @@ filegroup { } EOF - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build touch a/a2.txt # No reference in the .bp file needed - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build [[ -L out/soong/workspace/a/a2.txt ]] || fail "a/a2.txt not symlinked" } @@ -696,7 +713,7 @@ filegroup { } EOF - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build [[ -L "out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked" [[ "$(readlink -f out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/${GENERATED_BUILD_FILE_NAME}"$ ]] \ || fail "${GENERATED_BUILD_FILE_NAME} files symlinked to the wrong place" @@ -725,7 +742,7 @@ filegroup { } EOF - if GENERATE_BAZEL_FILES=1 run_soong >& "$MOCK_TOP/errors"; then + if run_soong bp2build >& "$MOCK_TOP/errors"; then fail "Build should have failed" fi @@ -739,7 +756,7 @@ function test_bp2build_back_and_forth_null_build { run_soong local output_mtime1=$(stat -c "%y" out/soong/build.ninja) - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build local output_mtime2=$(stat -c "%y" out/soong/build.ninja) if [[ "$output_mtime1" != "$output_mtime2" ]]; then fail "Output Ninja file changed when switching to bp2build" @@ -757,7 +774,7 @@ function test_bp2build_back_and_forth_null_build { fail "bp2build marker file changed when switching to regular build from bp2build" fi - GENERATE_BAZEL_FILES=1 run_soong + run_soong bp2build local output_mtime4=$(stat -c "%y" out/soong/build.ninja) local marker_mtime3=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) if [[ "$output_mtime1" != "$output_mtime4" ]]; then @@ -780,6 +797,7 @@ test_delete_android_bp test_add_file_to_soong_build test_glob_during_bootstrapping test_soong_build_rerun_iff_environment_changes +test_multiple_soong_build_modes test_dump_json_module_graph test_json_module_graph_back_and_forth_null_build test_write_to_source_tree diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh index 9bd85a414..379eb6548 100755 --- a/tests/bp2build_bazel_test.sh +++ b/tests/bp2build_bazel_test.sh @@ -10,10 +10,10 @@ readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel" function test_bp2build_null_build() { setup - run_bp2build + run_soong bp2build local output_mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) - run_bp2build + run_soong bp2build local output_mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) if [[ "$output_mtime1" != "$output_mtime2" ]]; then @@ -35,10 +35,10 @@ filegroup { EOF touch foo/bar/a.txt foo/bar/b.txt - run_bp2build + run_soong bp2build local output_mtime1=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) - run_bp2build + run_soong bp2build local output_mtime2=$(stat -c "%y" out/soong/.bootstrap/bp2build_workspace_marker) if [[ "$output_mtime1" != "$output_mtime2" ]]; then @@ -80,7 +80,7 @@ genrule { } EOF - run_bp2build + 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" diff --git a/tests/lib.sh b/tests/lib.sh index 813a9dd7d..e77782066 100644 --- a/tests/lib.sh +++ b/tests/lib.sh @@ -124,10 +124,6 @@ run_bazel() { tools/bazel "$@" } -run_bp2build() { - GENERATE_BAZEL_FILES=true build/soong/soong_ui.bash --make-mode --skip-ninja --skip-make --skip-soong-tests nothing -} - run_ninja() { build/soong/soong_ui.bash --make-mode --skip-make --skip-soong-tests "$@" } diff --git a/ui/build/build.go b/ui/build/build.go index d869bf0bc..2e44aaac6 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -248,6 +248,16 @@ func Build(ctx Context, config Config) { what = what &^ RunNinja } + if !config.SoongBuildInvocationNeeded() { + // This means that the output of soong_build is not needed and thus it would + // run unnecessarily. In addition, if this code wasn't there invocations + // with only special-cased target names like "m bp2build" would result in + // passing Ninja the empty target list and it would then build the default + // targets which is not what the user asked for. + what = what &^ RunNinja + what = what &^ RunKati + } + if config.StartGoma() { startGoma(ctx, config) } @@ -278,16 +288,6 @@ func Build(ctx Context, config Config) { if what&RunSoong != 0 { runSoong(ctx, config) - - if config.bazelBuildMode() == generateBuildFiles { - // Return early, if we're using Soong as solely the generator of BUILD files. - return - } - - if config.bazelBuildMode() == generateJsonModuleGraph { - // Return early, if we're using Soong as solely the generator of the JSON module graph - return - } } if what&RunKati != 0 { diff --git a/ui/build/config.go b/ui/build/config.go index 6de7a050b..0b93b189c 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -33,7 +33,8 @@ import ( type Config struct{ *configImpl } type configImpl struct { - // From the environment + // Some targets that are implemented in soong_build + // (bp2build, json-module-graph) are not here and have their own bits below. arguments []string goma bool environ *Environment @@ -41,17 +42,19 @@ type configImpl struct { buildDateTime string // From the arguments - parallel int - keepGoing int - verbose bool - checkbuild bool - dist bool - skipConfig bool - skipKati bool - skipKatiNinja bool - skipSoong bool - skipNinja bool - skipSoongTests bool + parallel int + keepGoing int + verbose bool + checkbuild bool + dist bool + jsonModuleGraph bool + bp2build bool + skipConfig bool + skipKati bool + skipKatiNinja bool + skipSoong bool + skipNinja bool + skipSoongTests bool // From the product config katiArgs []string @@ -109,9 +112,6 @@ const ( // Only generate build files (in a subdirectory of the out directory) and exit. generateBuildFiles - // Only generate the Soong json module graph for use with jq, and exit. - generateJsonModuleGraph - // Generate synthetic build files and incorporate these files into a build which // partially uses Bazel. Build metadata may come from Android.bp or BUILD files. mixedBuild @@ -639,6 +639,10 @@ func (c *configImpl) parseArgs(ctx Context, args []string) { c.environ.Set(k, v) } else if arg == "dist" { c.dist = true + } else if arg == "json-module-graph" { + c.jsonModuleGraph = true + } else if arg == "bp2build" { + c.bp2build = true } else { if arg == "checkbuild" { c.checkbuild = true @@ -705,6 +709,26 @@ func (c *configImpl) Arguments() []string { return c.arguments } +func (c *configImpl) SoongBuildInvocationNeeded() bool { + if c.Dist() { + return true + } + + if len(c.Arguments()) > 0 { + // Explicit targets requested that are not special targets like b2pbuild + // or the JSON module graph + return true + } + + if !c.JsonModuleGraph() && !c.Bp2Build() { + // Command line was empty, the default Ninja target is built + return true + } + + // build.ninja doesn't need to be generated + return false +} + func (c *configImpl) OutDir() string { if outDir, ok := c.environ.Get("OUT_DIR"); ok { return outDir @@ -790,6 +814,14 @@ func (c *configImpl) Dist() bool { return c.dist } +func (c *configImpl) JsonModuleGraph() bool { + return c.jsonModuleGraph +} + +func (c *configImpl) Bp2Build() bool { + return c.bp2build +} + func (c *configImpl) IsVerbose() bool { return c.verbose } @@ -935,10 +967,6 @@ func (c *configImpl) UseBazel() bool { func (c *configImpl) bazelBuildMode() bazelBuildMode { if c.Environment().IsEnvTrue("USE_BAZEL_ANALYSIS") { return mixedBuild - } else if c.Environment().IsEnvTrue("GENERATE_BAZEL_FILES") { - return generateBuildFiles - } else if c.Environment().IsEnvTrue("GENERATE_JSON_MODULE_GRAPH") { - return generateJsonModuleGraph } else { return noBazel } diff --git a/ui/build/soong.go b/ui/build/soong.go index d4f6f2f81..fef30dad1 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -275,7 +275,7 @@ func runSoong(ctx Context, config Config) { } buildMode := config.bazelBuildMode() - integratedBp2Build := (buildMode == mixedBuild) || (buildMode == generateBuildFiles) + integratedBp2Build := buildMode == mixedBuild // This is done unconditionally, but does not take a measurable amount of time bootstrapBlueprint(ctx, config) @@ -351,18 +351,22 @@ func runSoong(ctx Context, config Config) { cmd.RunAndStreamOrFatal() } - var target string + targets := make([]string, 0, 0) - if config.bazelBuildMode() == generateBuildFiles { - target = config.Bp2BuildMarkerFile() - } else if config.bazelBuildMode() == generateJsonModuleGraph { - target = config.ModuleGraphFile() - } else { - // This build generates /build.ninja, which is used later by build/soong/ui/build/build.go#Build(). - target = config.MainNinjaFile() + if config.JsonModuleGraph() { + targets = append(targets, config.ModuleGraphFile()) } - ninja("bootstrap", ".bootstrap/build.ninja", target) + if config.Bp2Build() { + targets = append(targets, config.Bp2BuildMarkerFile()) + } + + if config.SoongBuildInvocationNeeded() { + // This build generates /build.ninja, which is used later by build/soong/ui/build/build.go#Build(). + targets = append(targets, config.MainNinjaFile()) + } + + ninja("bootstrap", ".bootstrap/build.ninja", targets...) var soongBuildMetrics *soong_metrics_proto.SoongBuildMetrics if shouldCollectBuildSoongMetrics(config) { @@ -404,7 +408,7 @@ func runMicrofactory(ctx Context, config Config, relExePath string, pkg string, func shouldCollectBuildSoongMetrics(config Config) bool { // Do not collect metrics protobuf if the soong_build binary ran as the // bp2build converter or the JSON graph dump. - return config.bazelBuildMode() != generateBuildFiles && config.bazelBuildMode() != generateJsonModuleGraph + return config.SoongBuildInvocationNeeded() } func loadSoongBuildMetrics(ctx Context, config Config) *soong_metrics_proto.SoongBuildMetrics {