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

Commit 80b29a21 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Update SOONG_PARTIAL_COMPILE logic" into main

parents f41f0e5c 99f18960
Loading
Loading
Loading
Loading
+104 −0
Original line number Diff line number Diff line
@@ -324,6 +324,9 @@ type config struct {
	AndroidCommonTarget      Target // the Target for common modules for the Android device
	AndroidFirstDeviceTarget Target // the first Target for modules for the Android device

	// Flags for Partial Compile, derived from SOONG_PARTIAL_COMPILE.
	partialCompileFlags partialCompileFlags

	// multilibConflicts for an ArchType is true if there is earlier configured
	// device architecture with the same multilib value.
	multilibConflicts map[ArchType]bool
@@ -373,6 +376,16 @@ type config struct {
	ensureAllowlistIntegrity bool
}

type partialCompileFlags struct {
	// Is partial compilation enabled at all?
	enabled bool

	// Whether to use d8 instead of r8
	use_d8 bool

	// Add others as needed.
}

type deviceConfig struct {
	config *config
	OncePer
@@ -382,6 +395,88 @@ type jsonConfigurable interface {
	SetDefaultConfig()
}

// Parse SOONG_PARTIAL_COMPILE.
//
// SOONG_PARTIAL_COMPILE determines which features are enabled or disabled in
// rule generation.  Changing this environment variable causes reanalysis.
//
// SOONG_USE_PARTIAL_COMPILE determines whether or not we **use** PARTIAL_COMPILE.
// Rule generation must support both cases, since changing it does not cause
// reanalysis.
//
// The user-facing documentation shows:
//
// - empty or not set: "The current default state"
// - "true" or "on": enable all stable partial compile features.
// - "false" or "off": disable partial compile completely.
//
// What we actually allow is a comma separated list of tokens, whose first
// character may be "+" (enable) or "-" (disable).  If neither is present, "+"
// is assumed.  For example, "on,+use_d8" will enable partial compilation, and
// additionally set the use_d8 flag (regardless of whether it is opt-in or
// opt-out).
//
// To add a new feature to the list, add the field in the struct
// `partialCompileFlags` above, and then add the name of the field in the
// switch statement below.
func (c *config) parsePartialCompileFlags() (partialCompileFlags, error) {
	defaultFlags := partialCompileFlags{
		// Set any opt-out flags here.  Opt-in flags are off by default.
		enabled: false,
	}
	value := c.Getenv("SOONG_PARTIAL_COMPILE")

	if value == "" {
		return defaultFlags, nil
	}

	ret := defaultFlags
	tokens := strings.Split(strings.ToLower(value), ",")
	makeVal := func(state string, defaultValue bool) bool {
		switch state {
		case "":
			return defaultValue
		case "-":
			return false
		case "+":
			return true
		}
		return false
	}
	for _, tok := range tokens {
		var state string
		if len(tok) == 0 {
			continue
		}
		switch tok[0:1] {
		case "":
			// Ignore empty tokens.
			continue
		case "-", "+":
			state = tok[0:1]
			tok = tok[1:]
		default:
			// Treat `feature` as `+feature`.
			state = "+"
		}
		switch tok {
		case "true":
			ret = defaultFlags
			ret.enabled = true
		case "false":
			// Set everything to false.
			ret = partialCompileFlags{}
		case "enabled":
			ret.enabled = makeVal(state, defaultFlags.enabled)
		case "use_d8":
			ret.use_d8 = makeVal(state, defaultFlags.use_d8)
		default:
			return partialCompileFlags{}, fmt.Errorf("Unknown SOONG_PARTIAL_COMPILE value: %v", value)
		}
	}
	return ret, nil
}

func loadConfig(config *config) error {
	return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName))
}
@@ -568,6 +663,11 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error)
		return Config{}, err
	}

	config.partialCompileFlags, err = config.parsePartialCompileFlags()
	if err != nil {
		return Config{}, err
	}

	// Make the CommonOS OsType available for all products.
	targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]}

@@ -999,6 +1099,10 @@ func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel {
	return ApiLevelOrPanic(ctx, codename)
}

func (c *config) PartialCompileFlags() partialCompileFlags {
	return c.partialCompileFlags
}

func (c *config) AppsDefaultVersionName() string {
	return String(c.productVariables.AppsDefaultVersionName)
}
+14 −90
Original line number Diff line number Diff line
@@ -98,7 +98,6 @@ type configImpl struct {
	buildFromSourceStub      bool
	incrementalBuildActions  bool
	ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
	partialCompileFlags      partialCompileFlags

	// From the product config
	katiArgs        []string
@@ -138,16 +137,6 @@ type configImpl struct {
	ninjaCommand ninjaCommandType
}

type partialCompileFlags struct {
	// Is partial compilation enabled at all?
	enabled bool

	// Whether to use d8 instead of r8
	use_d8 bool

	// Add others as needed.
}

type NinjaWeightListSource uint

const (
@@ -304,12 +293,24 @@ func NewConfig(ctx Context, args ...string) Config {
		ret.sandboxConfig.SetSrcDirIsRO(srcDirIsWritable == "false")
	}

	ret.partialCompileFlags = parsePartialCompileFlags(ctx)

	if os.Getenv("GENERATE_SOONG_DEBUG") == "true" {
		ret.moduleDebugFile, _ = filepath.Abs(shared.JoinPath(ret.SoongOutDir(), "soong-debug-info.json"))
	}

	// If SOONG_USE_PARTIAL_COMPILE is set, make it one of "true" or the empty string.
	// This simplifies the generated Ninja rules, so that they only need to check for the empty string.
	if value, ok := os.LookupEnv("SOONG_USE_PARTIAL_COMPILE"); ok {
		if value == "true" || value == "1" || value == "y" || value == "yes" {
			value = "true"
		} else {
			value = ""
		}
		err = os.Setenv("SOONG_USE_PARTIAL_COMPILE", value)
		if err != nil {
			ctx.Fatalln("Failed to set SOONG_USE_PARTIAL_COMPILE: %v", err)
		}
	}

	ret.ninjaCommand = NINJA_NINJA
	switch os.Getenv("SOONG_NINJA") {
	case "n2":
@@ -382,7 +383,6 @@ func NewConfig(ctx Context, args ...string) Config {
		// Use config.ninjaCommand instead.
		"SOONG_NINJA",
		"SOONG_USE_N2",
		"SOONG_PARTIAL_COMPILE",
	)

	if ret.UseGoma() || ret.ForceUseGoma() {
@@ -501,78 +501,6 @@ func NewConfig(ctx Context, args ...string) Config {
	return c
}

// Parse SOONG_PARTIAL_COMPILE.
//
// The user-facing documentation shows:
//
// - empty or not set: "The current default state"
// - "true" or "on": enable all stable partial compile features.
// - "false" or "off": disable partial compile completely.
//
// What we actually allow is a comma separated list of tokens, whose first
// character may be "+" (enable) or "-" (disable).  If neither is present, "+"
// is assumed.  For example, "on,+use_d8" will enable partial compilation, and
// additionally set the use_d8 flag (regardless of whether it is opt-in or
// opt-out).
//
// To add a new feature to the list, add the field in the struct
// `partialCompileFlags` above, and then add the name of the field in the
// switch statement below.
func parsePartialCompileFlags(ctx Context) partialCompileFlags {
	defaultFlags := partialCompileFlags{
		// Set any opt-out flags here.  Opt-in flags are off by default.
		enabled: false,
	}
	value, ok := os.LookupEnv("SOONG_PARTIAL_COMPILE")

	if !ok {
		return defaultFlags
	}

	ret := defaultFlags
	tokens := strings.Split(strings.ToLower(value), ",")
	makeVal := func(state string, defaultValue bool) bool {
		switch state {
		case "":
			return defaultValue
		case "-":
			return false
		case "+":
			return true
		}
		return false
	}
	for _, tok := range tokens {
		var state string
		switch tok[0:1] {
		case "":
			// Ignore empty tokens.
			continue
		case "-", "+":
			state = tok[0:1]
			tok = tok[1:]
		default:
			// Treat `feature` as `+feature`.
			state = "+"
		}
		switch tok {
		case "true", "on", "yes":
			ret = defaultFlags
			ret.enabled = true
		case "false", "off", "no":
			// Set everything to false.
			ret = partialCompileFlags{}
		case "enabled":
			ret.enabled = makeVal(state, defaultFlags.enabled)
		case "use_d8":
			ret.use_d8 = makeVal(state, defaultFlags.use_d8)
		default:
			ctx.Fatalln("Unknown SOONG_PARTIAL_COMPILE value:", value)
		}
	}
	return ret
}

// NewBuildActionConfig returns a build configuration based on the build action. The arguments are
// processed based on the build action and extracts any arguments that belongs to the build action.
func NewBuildActionConfig(action BuildAction, dir string, ctx Context, args ...string) Config {
@@ -1855,10 +1783,6 @@ func (c *configImpl) EnsureAllowlistIntegrity() bool {
	return c.ensureAllowlistIntegrity
}

func (c *configImpl) PartialCompileFlags() partialCompileFlags {
	return c.partialCompileFlags
}

// Returns a Time object if one was passed via a command-line flag.
// Otherwise returns the passed default.
func (c *configImpl) BuildStartedTimeOrDefault(defaultTime time.Time) time.Time {
+17 −0
Original line number Diff line number Diff line
@@ -183,6 +183,23 @@ func runKati(ctx Context, config Config, extraSuffix string, args []string, envF
		username = usernameFromEnv
	}

	// SOONG_USE_PARTIAL_COMPILE may be used in makefiles, but both cases must be supported.
	//
	// In general, the partial compile features will be implemented in Soong-based rules. We
	// also allow them to be used in makefiles.  Clear the environment variable when calling
	// kati so that we avoid reanalysis when the user changes it.  We will pass it to Ninja.
	// As a result, rules where we want to allow the developer to toggle the feature ("use
	// the partial compile feature" vs "legacy, aka full compile behavior") need to use this
	// in the rule, since changing it will not cause reanalysis.
	//
	// Shell syntax in the rule might look something like this:
	//     if [[ -n ${SOONG_USE_PARTIAL_COMPILE} ]]; then
	//         # partial compile behavior
	//     else
	//         # legacy behavior
	//     fi
	cmd.Environment.Unset("SOONG_USE_PARTIAL_COMPILE")

	hostname, ok := cmd.Environment.Get("BUILD_HOSTNAME")
	// Unset BUILD_HOSTNAME during kati run to avoid kati rerun, kati will use BUILD_HOSTNAME from a file.
	cmd.Environment.Unset("BUILD_HOSTNAME")
+3 −0
Original line number Diff line number Diff line
@@ -241,6 +241,9 @@ func runNinjaForBuild(ctx Context, config Config) {
			"SOONG_USE_N2",
			"RUST_BACKTRACE",
			"RUST_LOG",

			// SOONG_USE_PARTIAL_COMPILE only determines which half of the rule we execute.
			"SOONG_USE_PARTIAL_COMPILE",
		}, config.BuildBrokenNinjaUsesEnvVars()...)...)
	}