• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"os"
19	"os/exec"
20	"strings"
21
22	"android/soong/env"
23)
24
25// This file supports dependencies on environment variables.  During build manifest generation,
26// any dependency on an environment variable is added to a list.  During the singleton phase
27// a JSON file is written containing the current value of all used environment variables.
28// The next time the top-level build script is run, it uses the soong_env executable to
29// compare the contents of the environment variables, rewriting the file if necessary to cause
30// a manifest regeneration.
31
32var originalEnv map[string]string
33var SoongDelveListen string
34var SoongDelvePath string
35
36func init() {
37	// Delve support needs to read this environment variable very early, before NewConfig has created a way to
38	// access originalEnv with dependencies.  Store the value where soong_build can find it, it will manually
39	// ensure the dependencies are created.
40	SoongDelveListen = os.Getenv("SOONG_DELVE")
41	SoongDelvePath, _ = exec.LookPath("dlv")
42
43	originalEnv = make(map[string]string)
44	for _, env := range os.Environ() {
45		idx := strings.IndexRune(env, '=')
46		if idx != -1 {
47			originalEnv[env[:idx]] = env[idx+1:]
48		}
49	}
50	// Clear the environment to prevent use of os.Getenv(), which would not provide dependencies on environment
51	// variable values.  The environment is available through ctx.Config().Getenv, ctx.Config().IsEnvTrue, etc.
52	os.Clearenv()
53}
54
55// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
56// function above.  It doesn't add any dependencies on the environment variable, so it should
57// only be used for values that won't change.  For values that might change use ctx.Config().Getenv.
58func getenv(key string) string {
59	if originalEnv == nil {
60		return os.Getenv(key)
61	} else {
62		return originalEnv[key]
63	}
64}
65
66func EnvSingleton() Singleton {
67	return &envSingleton{}
68}
69
70type envSingleton struct{}
71
72func (c *envSingleton) GenerateBuildActions(ctx SingletonContext) {
73	envDeps := ctx.Config().EnvDeps()
74
75	envFile := PathForOutput(ctx, ".soong.environment")
76	if ctx.Failed() {
77		return
78	}
79
80	data, err := env.EnvFileContents(envDeps)
81	if err != nil {
82		ctx.Errorf(err.Error())
83	}
84
85	err = WriteFileToOutputDir(envFile, data, 0666)
86	if err != nil {
87		ctx.Errorf(err.Error())
88	}
89
90	ctx.AddNinjaFileDeps(envFile.String())
91}
92