aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/cpp/cpp.go95
-rw-r--r--build/cpp/gcc/gcc.go34
-rw-r--r--build/cpp/ndk/ndk.go50
-rw-r--r--build/cpp/parse_depfile.go68
-rw-r--r--build/cpp/parse_depfile_test.go78
-rw-r--r--build/environment.go1
-rw-r--r--build/file.go12
-rw-r--r--build/file_set.go14
-rw-r--r--cc/build.go2
-rwxr-xr-xtools/make_gpu_tools.sh4
-rw-r--r--tools/make_gpu_tools_win.bat2
11 files changed, 322 insertions, 38 deletions
diff --git a/build/cpp/cpp.go b/build/cpp/cpp.go
index ca208a64c..95ac91437 100644
--- a/build/cpp/cpp.go
+++ b/build/cpp/cpp.go
@@ -24,6 +24,7 @@ import (
)
type tool func(inputs build.FileSet, output build.File, cfg Config, env build.Environment) error
+type depsFor func(output build.File, cfg Config, env build.Environment) (deps build.FileSet, valid bool)
var sourcePatterns = []string{"*.cpp", "*.c", "*.cc", "*.mm"}
@@ -32,6 +33,7 @@ type Toolchain struct {
Compiler tool // Tool used to compile source to object files.
Archiver tool // Tool used to package object files into archives.
Linker tool // Tool used to link objects and packages into executables.
+ DepsFor depsFor // Returns the list of dependencies for the given file.
ExeName func(Config) string // Returns the name of the emitted executable.
LibName func(Config) string // Returns the name of the emitted static library file.
ObjExt func(Config) string // Extension used for object files.
@@ -117,18 +119,49 @@ func Compile(sources build.FileSet, cfg Config, env build.Environment) (build.Fi
wg.Add(len(sources))
for i, source := range sources {
i, source, env := i, source, env
- env.Logger = env.Logger.Fork() // Give each go-routine a unique logger context id.
- go func() {
- defer wg.Done()
- object := IntermediatePath(source, cfg.Toolchain.ObjExt(cfg), cfg, env)
+ object := IntermediatePath(source, cfg.Toolchain.ObjExt(cfg), cfg, env)
+
+ if requiresCompile(source, object, cfg, env) {
+ env.Logger = env.Logger.Fork() // Give each go-routine a unique logger context id.
+ go func() {
+ defer wg.Done()
+ objects[i] = object
+ errors[i] = cfg.Toolchain.Compiler(build.FileSet{source}, object, cfg, env)
+ }()
+ } else {
objects[i] = object
- errors[i] = cfg.Toolchain.Compiler(build.FileSet{source}, object, cfg, env)
- }()
+ wg.Done()
+ if env.Verbose {
+ env.Logger.Info("%s is up-to-date", object)
+ }
+ }
}
wg.Wait()
return objects, combineErrors(errors)
}
+func requiresCompile(source, output build.File, cfg Config, env build.Environment) bool {
+ if env.ForceBuild {
+ return true
+ }
+ if !output.Exists() {
+ return true
+ }
+ t := output.LastModified()
+ if source.LastModified().After(t) {
+ return true
+ }
+ depsFor := cfg.Toolchain.DepsFor
+ if depsFor == nil {
+ return true // If the toolchain can't check dependencies, then we have to build
+ }
+ deps, valid := depsFor(output, cfg, env)
+ if !valid || deps.LastModified().After(t) {
+ return true
+ }
+ return false
+}
+
// Executable links the list of input files into an executable using the Config
// and build Environment. The inputs can be a combination of source files,
// object files and / or library files. Compile returns the output executable
@@ -143,19 +176,39 @@ func Executable(inputs build.FileSet, cfg Config, env build.Environment) (build.
objects = objects.Append(inputs.Filter("*" + cfg.Toolchain.ObjExt(cfg))...)
- sourceLibraries := build.FileSet{}
+ libraries := build.FileSet{}
for _, library := range inputs.Filter("*" + cfg.Toolchain.LibExt(cfg)) {
dir, base := filepath.Split(library.Absolute())
- sourceLibraries = sourceLibraries.Append(build.File(base))
+ libraries = libraries.Append(build.File(base))
cfg.LibrarySearchPaths = cfg.LibrarySearchPaths.Append(build.File(dir))
}
- cfg.Libraries = append(sourceLibraries, cfg.Libraries...)
+ cfg.Libraries = append(libraries, cfg.Libraries...)
output := env.Output.Join(cfg.Toolchain.ExeName(cfg))
output.MkdirAll()
- return output, cfg.Toolchain.Linker(objects, output, cfg, env)
+ if requiresLink(inputs.Append(objects...), output, env) {
+ return output, cfg.Toolchain.Linker(objects, output, cfg, env)
+ } else {
+ if env.Verbose {
+ env.Logger.Info("%s is up-to-date", output)
+ }
+ return output, nil
+ }
+}
+
+func requiresLink(inputs build.FileSet, output build.File, env build.Environment) bool {
+ if env.ForceBuild {
+ return true
+ }
+ if !output.Exists() {
+ return true
+ }
+ if inputs.LastModified().After(output.LastModified()) {
+ return true
+ }
+ return false
}
// StaticLibrary archives the list of input files into an static library using
@@ -176,7 +229,27 @@ func StaticLibrary(inputs build.FileSet, cfg Config, env build.Environment) (bui
output := env.Intermediates.Join(Triplet(cfg), name).ChangeExt(cfg.Toolchain.LibExt(cfg))
output.MkdirAll()
- return output, cfg.Toolchain.Archiver(objects, output, cfg, env)
+ if requiresArchive(objects, output, env) {
+ return output, cfg.Toolchain.Archiver(objects, output, cfg, env)
+ } else {
+ if env.Verbose {
+ env.Logger.Info("%s is up-to-date", output)
+ }
+ return output, nil
+ }
+}
+
+func requiresArchive(objects build.FileSet, output build.File, env build.Environment) bool {
+ if env.ForceBuild {
+ return true
+ }
+ if !output.Exists() {
+ return true
+ }
+ if objects.LastModified().After(output.LastModified()) {
+ return true
+ }
+ return false
}
// Triplet returns a string combining the os, architecture and flavour of cfg.
diff --git a/build/cpp/gcc/gcc.go b/build/cpp/gcc/gcc.go
index 6297e6270..475b8647e 100644
--- a/build/cpp/gcc/gcc.go
+++ b/build/cpp/gcc/gcc.go
@@ -24,9 +24,10 @@ import (
)
var GCC = &cpp.Toolchain{
- Compiler: gccCompile,
- Archiver: gccArchive,
- Linker: gccLink,
+ Compiler: compile,
+ Archiver: archive,
+ Linker: link,
+ DepsFor: depsFor,
ExeName: func(cfg cpp.Config) string {
if cfg.OS == "windows" {
return cfg.Name + ".exe"
@@ -83,7 +84,11 @@ func getTools(cfg cpp.Config) (*tools, error) {
return &t, nil
}
-func gccCompile(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func depFileFor(output build.File, cfg cpp.Config, env build.Environment) build.File {
+ return cpp.IntermediatePath(output, ".dep", cfg, env)
+}
+
+func compile(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("GCC.Compile")
tools, err := getTools(cfg)
@@ -91,7 +96,12 @@ func gccCompile(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return err
}
- a := append([]string{"-c"}, cfg.CompilerArgs...)
+ depfile := depFileFor(output, cfg, env)
+
+ a := append([]string{
+ "-c", // Compile to .o
+ "-MMD", "-MF", depfile.Absolute(), // Generate dependency file
+ }, cfg.CompilerArgs...)
for _, isp := range cfg.IncludeSearchPaths {
a = append(a, fmt.Sprintf("-I%s", isp))
}
@@ -101,11 +111,11 @@ func gccCompile(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
for _, input := range inputs {
a = append(a, input.Absolute())
}
- a = append(a, "-v", "-o", string(output))
+ a = append(a, "-o", string(output))
return tools.cc.Exec(env, a...)
}
-func gccArchive(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func archive(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("GCC.Archive")
tools, err := getTools(cfg)
@@ -122,7 +132,7 @@ func gccArchive(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return tools.ar.Exec(env, a...)
}
-func gccLink(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func link(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("GCC.Link")
tools, err := getTools(cfg)
@@ -144,3 +154,11 @@ func gccLink(inputs build.FileSet, output build.File, cfg cpp.Config, env build.
a = append(a, "-o", string(output))
return tools.cc.Exec(env, a...)
}
+
+func depsFor(output build.File, cfg cpp.Config, env build.Environment) (deps build.FileSet, valid bool) {
+ env.Logger = env.Logger.Enter("GCC.Deps")
+
+ depfile := depFileFor(output, cfg, env)
+
+ return cpp.ParseDepFile(depfile, env)
+}
diff --git a/build/cpp/ndk/ndk.go b/build/cpp/ndk/ndk.go
index 625e88233..b998e0e7c 100644
--- a/build/cpp/ndk/ndk.go
+++ b/build/cpp/ndk/ndk.go
@@ -49,9 +49,10 @@ var osToSystem = map[string]string{
// Toolchain for building an Android executable env, without being packaged into an
// APK (user-debug only).
var EXE = &cpp.Toolchain{
- Compiler: ndkCompile,
- Archiver: ndkArchive,
- Linker: ndkLinkExe,
+ Compiler: compile,
+ Archiver: archive,
+ Linker: linkExe,
+ DepsFor: depsFor,
ExeName: func(cfg cpp.Config) string { return fmt.Sprintf("%s-%s", cfg.Name, cfg.Architecture) },
LibName: func(cfg cpp.Config) string { return "lib" + cfg.Name + ".a" },
ObjExt: func(cfg cpp.Config) string { return ".o" },
@@ -59,9 +60,10 @@ var EXE = &cpp.Toolchain{
// Toolchain for building an Android shared library.
var SO = &cpp.Toolchain{
- Compiler: ndkCompile,
- Archiver: ndkArchive,
- Linker: ndkLinkSo,
+ Compiler: compile,
+ Archiver: archive,
+ Linker: linkSo,
+ DepsFor: depsFor,
ExeName: func(cfg cpp.Config) string { return fmt.Sprintf("%s-%s.so", cfg.Name, cfg.Architecture) },
LibName: func(cfg cpp.Config) string { return "lib" + cfg.Name + ".a" },
ObjExt: func(cfg cpp.Config) string { return ".o" },
@@ -69,9 +71,10 @@ var SO = &cpp.Toolchain{
// Toolchain for building an Android APK.
var APK = &cpp.Toolchain{
- Compiler: ndkCompile,
- Archiver: ndkArchive,
- Linker: ndkLinkAPK,
+ Compiler: compile,
+ Archiver: archive,
+ Linker: linkAPK,
+ DepsFor: depsFor,
ExeName: func(cfg cpp.Config) string { return fmt.Sprintf("%s-%s.apk", cfg.Name, cfg.Architecture) },
LibName: func(cfg cpp.Config) string { return "lib" + cfg.Name + ".a" },
ObjExt: func(cfg cpp.Config) string { return ".o" },
@@ -131,7 +134,11 @@ func getTools(cfg cpp.Config) (*tools, error) {
}, nil
}
-func ndkCompile(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func depFileFor(output build.File, cfg cpp.Config, env build.Environment) build.File {
+ return cpp.IntermediatePath(output, ".dep", cfg, env)
+}
+
+func compile(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("NDK.Compile")
tools, err := getTools(cfg)
@@ -139,9 +146,12 @@ func ndkCompile(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return err
}
+ depfile := depFileFor(output, cfg, env)
+
a := []string{
"--sysroot=" + tools.sysroot.Absolute(),
- "-c",
+ "-c", // Compile to .o
+ "-MMD", "-MF", depfile.Absolute(), // Generate dependency file
"-fPIC", // TODO: Not required for exes
}
a = append(a, cfg.CompilerArgs...)
@@ -158,7 +168,7 @@ func ndkCompile(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return tools.cc.Exec(env, a...)
}
-func ndkArchive(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func archive(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("NDK.Archive")
tools, err := getTools(cfg)
@@ -175,7 +185,7 @@ func ndkArchive(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return tools.ar.Exec(env, a...)
}
-func ndkLinkExe(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func linkExe(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("NDK.Link-exe")
tools, err := getTools(cfg)
@@ -200,7 +210,7 @@ func ndkLinkExe(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return tools.cc.Exec(env, a...)
}
-func ndkLinkSo(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func linkSo(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("NDK.Link-so")
tools, err := getTools(cfg)
@@ -228,7 +238,7 @@ func ndkLinkSo(inputs build.FileSet, output build.File, cfg cpp.Config, env buil
return tools.cc.Exec(env, a...)
}
-func ndkLinkAPK(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
+func linkAPK(inputs build.FileSet, output build.File, cfg cpp.Config, env build.Environment) error {
env.Logger = env.Logger.Enter("NDK.Link-apk")
paths, err := ResolvePaths()
@@ -258,7 +268,7 @@ func ndkLinkAPK(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
ioutil.WriteFile(strings.Absolute(), stringsXml(cfg.Name), 0666)
so := root.Join("lib", ndkArchToTarget[cfg.Architecture].abi, "lib"+cfg.Name+".so")
so.MkdirAll()
- if err := ndkLinkSo(inputs, so, cfg, env); err != nil {
+ if err := linkSo(inputs, so, cfg, env); err != nil {
return err
}
@@ -302,6 +312,14 @@ func ndkLinkAPK(inputs build.FileSet, output build.File, cfg cpp.Config, env bui
return nil
}
+func depsFor(output build.File, cfg cpp.Config, env build.Environment) (deps build.FileSet, valid bool) {
+ env.Logger = env.Logger.Enter("NDK.Deps")
+
+ depfile := depFileFor(output, cfg, env)
+
+ return cpp.ParseDepFile(depfile, env)
+}
+
func androidManifest(cfg cpp.Config) []byte {
permissions := make([]string, len(cfg.Permissions))
for i := range cfg.Permissions {
diff --git a/build/cpp/parse_depfile.go b/build/cpp/parse_depfile.go
new file mode 100644
index 000000000..98b015ccc
--- /dev/null
+++ b/build/cpp/parse_depfile.go
@@ -0,0 +1,68 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// 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 cpp
+
+import (
+ "errors"
+ "io/ioutil"
+ "strings"
+
+ "android.googlesource.com/platform/tools/gpu/build"
+)
+
+// ParseDepFile loads and parses the makefile dependency file generated by the
+// C++ compiler. If parsing succeeds then ParseDepFile returns the list of file
+// dependencies in deps and depsValid is true, otherwise depsValid is false.
+func ParseDepFile(file build.File, env build.Environment) (deps build.FileSet, depsValid bool) {
+ if !file.Exists() {
+ // Dependency file not found - needs building.
+ return build.FileSet{}, false
+ }
+
+ f, err := ioutil.ReadFile(file.Absolute())
+ if err != nil {
+ env.Logger.Error("Could not read dependencies from '%s': %v", file, err)
+ return build.FileSet{}, false
+ }
+
+ deps, err = parseDeps(string(f))
+ if err != nil {
+ env.Logger.Error("Could not parse dependencies from '%s': %v", file, err)
+ return build.FileSet{}, false
+ }
+
+ return deps, true
+}
+
+func parseDeps(s string) (build.FileSet, error) {
+ p := strings.Split(s, ":")
+ if len(p) != 2 {
+ return build.FileSet{}, errors.New("Parse failure - no colon found")
+ }
+ s = p[1]
+
+ deps := build.FileSet{}
+ for _, s := range strings.FieldsFunc(s, func(r rune) bool {
+ switch r {
+ case '\\', '\t', '\n', ' ':
+ return true
+ default:
+ return false
+ }
+ }) {
+ deps = deps.Append(build.File(s))
+ }
+ return deps, nil
+}
diff --git a/build/cpp/parse_depfile_test.go b/build/cpp/parse_depfile_test.go
new file mode 100644
index 000000000..b04dd9716
--- /dev/null
+++ b/build/cpp/parse_depfile_test.go
@@ -0,0 +1,78 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// 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 cpp
+
+import (
+ "testing"
+
+ "android.googlesource.com/platform/tools/gpu/build"
+)
+
+func eq(a, b build.FileSet) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i := range a {
+ if a[i] != b[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func TestParseDeps(t *testing.T) {
+ for i, test := range []struct {
+ depfile string
+ expected build.FileSet
+ fail bool
+ }{
+ {
+ depfile: `/dev/gpu/pkg/osx-x64-release/foo/bar.o: /dev/gpu/src/foo/A.cpp`,
+ expected: build.FileSet{"/dev/gpu/src/foo/A.cpp"},
+ }, {
+ depfile: `/dev/gpu/pkg/osx-x64-release/foo/bar.o: \
+ /dev/gpu/src/foo/A.cpp \
+ /dev/gpu/src/foo/B.h /dev/gpu/src/foo/C.h \
+ /dev/gpu/src/foo/D.h
+`,
+ expected: build.FileSet{
+ "/dev/gpu/src/foo/A.cpp", "/dev/gpu/src/foo/B.h",
+ "/dev/gpu/src/foo/C.h", "/dev/gpu/src/foo/D.h",
+ },
+ }, {
+ depfile: ``,
+ fail: true,
+ }, {
+ depfile: `/dev/gpu/pkg/osx-x64-release/foo/bar.o /dev/gpu/src/foo/A.cpp`,
+ fail: true,
+ }, {
+ depfile: `/dev/gpu/pkg/osx-x64-release/foo/bar.o: a : b`,
+ fail: true,
+ },
+ } {
+ deps, err := parseDeps(test.depfile)
+ switch {
+ case test.fail && err == nil:
+ t.Errorf("%d Expected error, got none.", i)
+
+ case !test.fail && err != nil:
+ t.Errorf("%d Parse failure: %v", i, err)
+
+ case !eq(deps, test.expected):
+ t.Errorf("Dependencies were not as expected.\nExpected: %v\nGot: %v",
+ test.expected, deps)
+ }
+ }
+}
diff --git a/build/environment.go b/build/environment.go
index 77213b901..369fe2d5e 100644
--- a/build/environment.go
+++ b/build/environment.go
@@ -25,5 +25,6 @@ type Environment struct {
Keypass string // The password to the key in the keystore.
Keyalias string // The alias of the key used to sign APKs.
Logger log.Logger // The logger to emit log messages to.
+ ForceBuild bool // If true, all build steps will be forced.
Verbose bool // If true, logging should be verbose.
}
diff --git a/build/file.go b/build/file.go
index b215389d0..f949789e9 100644
--- a/build/file.go
+++ b/build/file.go
@@ -19,6 +19,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "time"
)
// File represents the path to a file or directory.
@@ -58,6 +59,15 @@ func (f File) Exists() bool {
return err == nil
}
+// LastModified returns the time the file was last modified.
+func (f File) LastModified() time.Time {
+ s, err := os.Stat(string(f.Absolute()))
+ if err != nil {
+ panic(err)
+ }
+ return s.ModTime()
+}
+
// Delete deletes the File.
func (f File) Delete() error {
return os.Remove(string(f))
@@ -166,6 +176,8 @@ func (f File) ExecAt(env Environment, wd File, args ...string) error {
case env.Verbose:
if msg := string(buffer.Bytes()); msg != "" {
logger.Info("\n%s\n--- %s succeeded ---", string(buffer.Bytes()), f.Name())
+ } else {
+ logger.Info("%s succeeded", f.Name())
}
}
return err
diff --git a/build/file_set.go b/build/file_set.go
index b69267728..ec404d399 100644
--- a/build/file_set.go
+++ b/build/file_set.go
@@ -14,6 +14,8 @@
package build
+import "time"
+
// FileSet is a list of Files with no duplicates.
type FileSet []File
@@ -73,6 +75,18 @@ nextfile:
return out
}
+// LastModified returns the most recent time any of the files were modified.
+func (fs FileSet) LastModified() time.Time {
+ t := time.Time{}
+ for _, f := range fs {
+ m := f.LastModified()
+ if t.Before(m) {
+ t = m
+ }
+ }
+ return t
+}
+
func (fs FileSet) toMap() map[File]struct{} {
m := make(map[File]struct{}, len(fs))
for _, file := range fs {
diff --git a/cc/build.go b/cc/build.go
index ff652efa1..4e6b5a6dc 100644
--- a/cc/build.go
+++ b/cc/build.go
@@ -36,6 +36,7 @@ var (
keypass = flag.String("keypass", "android", "The password to the keystore's key")
keyalias = flag.String("alias", "androiddebugkey", "The alias of the key used to sign APKs")
logfile = flag.String("logfile", "", "Writes logging to a file instead of stdout")
+ forcebuild = flag.Bool("f", false, "All build steps will be forced")
verbose = flag.Bool("v", false, "Enable verbose logging")
)
@@ -73,6 +74,7 @@ func run() int {
Keypass: *keypass,
Keyalias: *keyalias,
Logger: logger,
+ ForceBuild: *forcebuild,
Verbose: *verbose,
}
diff --git a/tools/make_gpu_tools.sh b/tools/make_gpu_tools.sh
index 403d736c3..59a9f2173 100755
--- a/tools/make_gpu_tools.sh
+++ b/tools/make_gpu_tools.sh
@@ -75,7 +75,7 @@ go generate $GO_GENERATE_FLAGS $GPU_RELATIVE_SOURCE
go generate $GO_GENERATE_FLAGS $GPU_RELATIVE_SOURCE_PATH/memory
go build $GO_BUILD_FLAGS $GPU_BUILD_ROOT/bin/gazer $GPU_RELATIVE_SOURCE_PATH/server/cmd
-go run src/$GPU_RELATIVE_SOURCE_PATH/cc/build.go --v --runtests
+go run src/$GPU_RELATIVE_SOURCE_PATH/cc/build.go --v --f --runtests
# Kill any existing replay daemon before running tests.
killall replayd || true
@@ -95,7 +95,7 @@ fi
killall replayd || true
if [ $crosscompile_windows -eq 1 ]; then
- go run src/$GPU_RELATIVE_SOURCE_PATH/cc/build.go --v --targets=windows
+ go run src/$GPU_RELATIVE_SOURCE_PATH/cc/build.go --v --f --targets=windows
source $PROGDIR/setup_toolchain_linux_xc_win64.txt
go build $GO_BUILD_FLAGS $GPU_BUILD_ROOT/bin/windows_amd64/gazer.exe -ldflags="-extld=$CC" $GPU_RELATIVE_SOURCE_PATH/server/cmd
fi
diff --git a/tools/make_gpu_tools_win.bat b/tools/make_gpu_tools_win.bat
index 99dd6f5a9..f7838cbb0 100644
--- a/tools/make_gpu_tools_win.bat
+++ b/tools/make_gpu_tools_win.bat
@@ -32,4 +32,4 @@ go generate %GO_GENERATE_FLAGS% %GPU_RELATIVE_
go generate %GO_GENERATE_FLAGS% %GPU_RELATIVE_SOURCE_PATH%\memory
go build %GO_BUILD_FLAGS% %GPU_BUILD_ROOT%\bin\gazer.exe %GPU_RELATIVE_SOURCE_PATH%\server\cmd
-go run src/$GPU_RELATIVE_SOURCE_PATH/cc/build.go --v --runtests
+go run src/$GPU_RELATIVE_SOURCE_PATH/cc/build.go --v --f --runtests