Move version checking from Make into soong_ui
When kati keeps state around, it has to regenerate the ninja file every time the state is changed. So move the java version checking into soong_ui, where we can parallelize it with other operations instead of only checking it occasionally. Bug: 35970961 Test: Put java7 in PATH, m -j Test: Put java8-google in PATH, m -j Test: Put a space in TOP, m -j Test: OUT_DIR=<case-preserving fs> m -j Test: OUT_DIR=<path with space> m -j Test: DIST_DIR=<path with sapce> m -j Change-Id: I3245c8dd6d856240d17d54cb05d593dc9df71a27
This commit is contained in:
parent
0b73b4bc37
commit
db8457cfec
|
@ -25,6 +25,7 @@ bootstrap_go_package {
|
|||
"context.go",
|
||||
"environment.go",
|
||||
"exec.go",
|
||||
"java.go",
|
||||
"kati.go",
|
||||
"make.go",
|
||||
"ninja.go",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
@ -59,6 +60,37 @@ const (
|
|||
BuildAll = BuildProductConfig | BuildSoong | BuildKati | BuildNinja
|
||||
)
|
||||
|
||||
func checkCaseSensitivity(ctx Context, config Config) {
|
||||
outDir := config.OutDir()
|
||||
lowerCase := filepath.Join(outDir, "casecheck.txt")
|
||||
upperCase := filepath.Join(outDir, "CaseCheck.txt")
|
||||
lowerData := "a"
|
||||
upperData := "B"
|
||||
|
||||
err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0777)
|
||||
if err != nil {
|
||||
ctx.Fatalln("Failed to check case sensitivity:", err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(upperCase, []byte(upperData), 0777)
|
||||
if err != nil {
|
||||
ctx.Fatalln("Failed to check case sensitivity:", err)
|
||||
}
|
||||
|
||||
res, err := ioutil.ReadFile(lowerCase)
|
||||
if err != nil {
|
||||
ctx.Fatalln("Failed to check case sensitivity:", err)
|
||||
}
|
||||
|
||||
if string(res) != lowerData {
|
||||
ctx.Println("************************************************************")
|
||||
ctx.Println("You are building on a case-insensitive filesystem.")
|
||||
ctx.Println("Please move your source tree to a case-sensitive filesystem.")
|
||||
ctx.Println("************************************************************")
|
||||
ctx.Fatalln("Case-insensitive filesystems not supported")
|
||||
}
|
||||
}
|
||||
|
||||
// Build the tree. The 'what' argument can be used to chose which components of
|
||||
// the build to run.
|
||||
func Build(ctx Context, config Config, what int) {
|
||||
|
@ -86,8 +118,13 @@ func Build(ctx Context, config Config, what int) {
|
|||
return
|
||||
}
|
||||
|
||||
// Start getting java version as early as possible
|
||||
getJavaVersions(ctx, config)
|
||||
|
||||
SetupOutDir(ctx, config)
|
||||
|
||||
checkCaseSensitivity(ctx, config)
|
||||
|
||||
if what&BuildProductConfig != 0 {
|
||||
// Run make for product config
|
||||
runMakeProductConfig(ctx, config)
|
||||
|
@ -99,6 +136,9 @@ func Build(ctx Context, config Config, what int) {
|
|||
runSoong(ctx, config)
|
||||
}
|
||||
|
||||
// Check the java versions we read earlier
|
||||
checkJavaVersion(ctx, config)
|
||||
|
||||
if what&BuildKati != 0 {
|
||||
// Run ckati
|
||||
runKati(ctx, config)
|
||||
|
|
|
@ -106,6 +106,32 @@ func NewConfig(ctx Context, args ...string) Config {
|
|||
log.Fatalln("Error verifying tree state:", err)
|
||||
}
|
||||
|
||||
if srcDir, err := filepath.Abs("."); err == nil {
|
||||
if strings.ContainsRune(srcDir, ' ') {
|
||||
log.Println("You are building in a directory whose absolute path contains a space character:")
|
||||
log.Println()
|
||||
log.Printf("%q\n", srcDir)
|
||||
log.Println()
|
||||
log.Fatalln("Directory names containing spaces are not supported")
|
||||
}
|
||||
}
|
||||
|
||||
if outDir := ret.OutDir(); strings.ContainsRune(outDir, ' ') {
|
||||
log.Println("The absolute path of your output directory ($OUT_DIR) contains a space character:")
|
||||
log.Println()
|
||||
log.Printf("%q\n", outDir)
|
||||
log.Println()
|
||||
log.Fatalln("Directory names containing spaces are not supported")
|
||||
}
|
||||
|
||||
if distDir := ret.DistDir(); strings.ContainsRune(distDir, ' ') {
|
||||
log.Println("The absolute path of your dist directory ($DIST_DIR) contains a space character:")
|
||||
log.Println()
|
||||
log.Printf("%q\n", distDir)
|
||||
log.Println()
|
||||
log.Fatalln("Directory names containing spaces are not supported")
|
||||
}
|
||||
|
||||
for _, arg := range args {
|
||||
arg = strings.TrimSpace(arg)
|
||||
if arg == "--make-mode" {
|
||||
|
|
|
@ -84,24 +84,38 @@ func (c *Cmd) StartOrFatal() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Cmd) reportError(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
if e, ok := err.(*exec.ExitError); ok {
|
||||
c.ctx.Fatalf("%s failed with: %v", c.name, e.ProcessState.String())
|
||||
} else {
|
||||
c.ctx.Fatalf("Failed to run %s: %v", c.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// RunOrFatal is equivalent to Run, but handles the error with a call to ctx.Fatal
|
||||
func (c *Cmd) RunOrFatal() {
|
||||
if err := c.Run(); err != nil {
|
||||
if e, ok := err.(*exec.ExitError); ok {
|
||||
c.ctx.Fatalf("%s failed with: %v", c.name, e.ProcessState.String())
|
||||
} else {
|
||||
c.ctx.Fatalf("Failed to run %s: %v", c.name, err)
|
||||
}
|
||||
}
|
||||
c.reportError(c.Run())
|
||||
}
|
||||
|
||||
// WaitOrFatal is equivalent to Wait, but handles the error with a call to ctx.Fatal
|
||||
func (c *Cmd) WaitOrFatal() {
|
||||
if err := c.Wait(); err != nil {
|
||||
if e, ok := err.(*exec.ExitError); ok {
|
||||
c.ctx.Fatalf("%s failed with: %v", c.name, e.ProcessState.String())
|
||||
} else {
|
||||
c.ctx.Fatalf("Failed to run %s: %v", c.name, err)
|
||||
}
|
||||
}
|
||||
c.reportError(c.Wait())
|
||||
}
|
||||
|
||||
// OutputOrFatal is equivalent to Output, but handles the error with a call to ctx.Fatal
|
||||
func (c *Cmd) OutputOrFatal() []byte {
|
||||
ret, err := c.Output()
|
||||
c.reportError(err)
|
||||
return ret
|
||||
}
|
||||
|
||||
// CombinedOutputOrFatal is equivalent to CombinedOutput, but handles the error with
|
||||
// a call to ctx.Fatal
|
||||
func (c *Cmd) CombinedOutputOrFatal() []byte {
|
||||
ret, err := c.CombinedOutput()
|
||||
c.reportError(err)
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const incompatibleJavacStr = "google"
|
||||
|
||||
var javaVersionInfo = struct {
|
||||
once sync.Once
|
||||
startOnce sync.Once
|
||||
|
||||
java_version_output string
|
||||
javac_version_output string
|
||||
}{}
|
||||
|
||||
func getJavaVersions(ctx Context, config Config) {
|
||||
javaVersionInfo.startOnce.Do(func() {
|
||||
go func() {
|
||||
if ctx.Tracer != nil {
|
||||
thread := ctx.Tracer.NewThread("java_version")
|
||||
ctx.Tracer.Begin("get version", thread)
|
||||
defer ctx.Tracer.End(thread)
|
||||
}
|
||||
|
||||
getJavaVersionsImpl(ctx, config)
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
func getJavaVersionsImpl(ctx Context, config Config) {
|
||||
javaVersionInfo.once.Do(func() {
|
||||
cmd := Command(ctx, config, "java", "java", "-version")
|
||||
cmd.Environment.Unset("_JAVA_OPTIONS")
|
||||
javaVersionInfo.java_version_output = string(cmd.CombinedOutputOrFatal())
|
||||
|
||||
cmd = Command(ctx, config, "javac", "javac", "-version")
|
||||
cmd.Environment.Unset("_JAVA_OPTIONS")
|
||||
javaVersionInfo.javac_version_output = string(cmd.CombinedOutputOrFatal())
|
||||
})
|
||||
}
|
||||
|
||||
func checkJavaVersion(ctx Context, config Config) {
|
||||
ctx.BeginTrace("java_version_check")
|
||||
defer ctx.EndTrace()
|
||||
|
||||
getJavaVersionsImpl(ctx, config)
|
||||
|
||||
var required_java_version string
|
||||
var java_version_regexp *regexp.Regexp
|
||||
var javac_version_regexp *regexp.Regexp
|
||||
if legacy, _ := config.Environment().Get("LEGACY_USE_JAVA7"); legacy != "" {
|
||||
required_java_version = "1.7"
|
||||
java_version_regexp = regexp.MustCompile(`^java .*[ "]1\.7[\. "$]`)
|
||||
javac_version_regexp = regexp.MustCompile(`[ "]1\.7[\. "$]`)
|
||||
} else {
|
||||
required_java_version = "1.8"
|
||||
java_version_regexp = regexp.MustCompile(`[ "]1\.8[\. "$]`)
|
||||
javac_version_regexp = java_version_regexp
|
||||
}
|
||||
|
||||
java_version := javaVersionInfo.java_version_output
|
||||
javac_version := javaVersionInfo.javac_version_output
|
||||
|
||||
found := false
|
||||
for _, l := range strings.Split(java_version, "\n") {
|
||||
if java_version_regexp.MatchString(l) {
|
||||
java_version = l
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
ctx.Println("***************************************************************")
|
||||
ctx.Println("You are attempting to build with the incorrect version of java.")
|
||||
ctx.Println()
|
||||
ctx.Println("Your version is:", java_version)
|
||||
ctx.Println("The required version is:", required_java_version+".x")
|
||||
ctx.Println()
|
||||
ctx.Println("Please follow the machine setup instructions at:")
|
||||
ctx.Println(" https://source.android.com/source/initializing.html")
|
||||
ctx.Println("***************************************************************")
|
||||
ctx.Fatalln("stop")
|
||||
}
|
||||
|
||||
if runtime.GOOS == "linux" {
|
||||
if !strings.Contains(java_version, "openjdk") {
|
||||
ctx.Println("*******************************************************")
|
||||
ctx.Println("You are attempting to build with an unsupported JDK.")
|
||||
ctx.Println()
|
||||
ctx.Println("Only an OpenJDK based JDK is supported.")
|
||||
ctx.Println()
|
||||
ctx.Println("Please follow the machine setup instructions at:")
|
||||
ctx.Println(" https://source.android.com/source/initializing.html")
|
||||
ctx.Println("*******************************************************")
|
||||
ctx.Fatalln("stop")
|
||||
}
|
||||
} else { // darwin
|
||||
if strings.Contains(java_version, "openjdk") {
|
||||
ctx.Println("*******************************************************")
|
||||
ctx.Println("You are attempting to build with an unsupported JDK.")
|
||||
ctx.Println()
|
||||
ctx.Println("You use OpenJDK, but only Sun/Oracle JDK is supported.")
|
||||
ctx.Println()
|
||||
ctx.Println("Please follow the machine setup instructions at:")
|
||||
ctx.Println(" https://source.android.com/source/initializing.html")
|
||||
ctx.Println("*******************************************************")
|
||||
ctx.Fatalln("stop")
|
||||
}
|
||||
}
|
||||
|
||||
incompatible_javac := strings.Contains(javac_version, incompatibleJavacStr)
|
||||
|
||||
found = false
|
||||
for _, l := range strings.Split(javac_version, "\n") {
|
||||
if javac_version_regexp.MatchString(l) {
|
||||
javac_version = l
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found || incompatible_javac {
|
||||
ctx.Println("****************************************************************")
|
||||
ctx.Println("You are attempting to build with the incorrect version of javac.")
|
||||
ctx.Println()
|
||||
ctx.Println("Your version is:", javac_version)
|
||||
if incompatible_javac {
|
||||
ctx.Println("The '" + incompatibleJavacStr + "' version is not supported for Android platform builds.")
|
||||
ctx.Println("Use a publically available JDK and make sure you have run envsetup.sh / lunch.")
|
||||
} else {
|
||||
ctx.Println("The required version is:", required_java_version)
|
||||
}
|
||||
ctx.Println()
|
||||
ctx.Println("Please follow the machine setup instructions at:")
|
||||
ctx.Println(" https://source.android.com/source/initializing.html")
|
||||
ctx.Println("****************************************************************")
|
||||
ctx.Fatalln("stop")
|
||||
}
|
||||
}
|
|
@ -46,6 +46,8 @@ type Tracer interface {
|
|||
Complete(name string, thread Thread, begin, end uint64)
|
||||
|
||||
ImportNinjaLog(thread Thread, filename string, startOffset time.Time)
|
||||
|
||||
NewThread(name string) Thread
|
||||
}
|
||||
|
||||
type tracerImpl struct {
|
||||
|
|
Loading…
Reference in New Issue