aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2015-11-24 17:53:15 -0800
committerDan Willemsen <dwillemsen@google.com>2015-11-30 15:28:31 -0800
commit490fd4955747c9d3715954359d72937960f02a22 (patch)
tree3b4ae5b86149ee178f60c21faf65e03ad7e23a51
parent3b336c20566becb20324e25deb52ee08d8b1f9f8 (diff)
downloadbuild_soong-490fd4955747c9d3715954359d72937960f02a22.tar.gz
build_soong-490fd4955747c9d3715954359d72937960f02a22.tar.bz2
build_soong-490fd4955747c9d3715954359d72937960f02a22.zip
Support cross-compiling Windows binaries on Linux
This defines another mutator between HostOrDevice and Arch that will expand host modules into a module for each host type (Darwin/Linux/Windows) that is currently being built. Change-Id: I4c8ac6b616c229f6bd45ad8a35902652fb6a4fff
-rw-r--r--Android.bp1
-rw-r--r--cc/arm64_device.go2
-rw-r--r--cc/arm_device.go2
-rw-r--r--cc/builder.go9
-rw-r--r--cc/cc.go115
-rw-r--r--cc/mips64_device.go2
-rw-r--r--cc/mips_device.go2
-rw-r--r--cc/toolchain.go36
-rw-r--r--cc/x86_64_device.go2
-rw-r--r--cc/x86_darwin_host.go13
-rw-r--r--cc/x86_device.go2
-rw-r--r--cc/x86_linux_host.go9
-rw-r--r--cc/x86_windows_host.go150
-rw-r--r--common/arch.go167
-rw-r--r--common/module.go36
-rw-r--r--common/variable.go10
-rw-r--r--genrule/genrule.go6
17 files changed, 469 insertions, 95 deletions
diff --git a/Android.bp b/Android.bp
index 4d1d7015..9a7beb82 100644
--- a/Android.bp
+++ b/Android.bp
@@ -130,6 +130,7 @@ bootstrap_go_package {
"cc/x86_darwin_host.go",
"cc/x86_linux_host.go",
+ "cc/x86_windows_host.go",
],
testSrcs: [
"cc/cc_test.go",
diff --git a/cc/arm64_device.go b/cc/arm64_device.go
index 4acb218d..9d58a809 100644
--- a/cc/arm64_device.go
+++ b/cc/arm64_device.go
@@ -155,5 +155,5 @@ func arm64ToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- registerToolchainFactory(common.Device, common.Arm64, arm64ToolchainFactory)
+ registerDeviceToolchainFactory(common.Arm64, arm64ToolchainFactory)
}
diff --git a/cc/arm_device.go b/cc/arm_device.go
index 746de2e3..2d6d38c5 100644
--- a/cc/arm_device.go
+++ b/cc/arm_device.go
@@ -362,5 +362,5 @@ func armToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- registerToolchainFactory(common.Device, common.Arm, armToolchainFactory)
+ registerDeviceToolchainFactory(common.Arm, armToolchainFactory)
}
diff --git a/cc/builder.go b/cc/builder.go
index e3b9983b..64437d28 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -33,7 +33,6 @@ import (
const (
objectExtension = ".o"
- sharedLibraryExtension = ".so"
staticLibraryExtension = ".a"
)
@@ -310,7 +309,7 @@ func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
var libFlagsList []string
if len(wholeStaticLibs) > 0 {
- if ctx.Host() && runtime.GOOS == "darwin" {
+ if ctx.Host() && ctx.Darwin() {
libFlagsList = append(libFlagsList, common.JoinWithPrefix(wholeStaticLibs, "-force_load "))
} else {
libFlagsList = append(libFlagsList, "-Wl,--whole-archive ")
@@ -334,11 +333,11 @@ func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
if !strings.HasPrefix(file, "lib") {
panic("shared library " + lib + " does not start with lib")
}
- if !strings.HasSuffix(file, sharedLibraryExtension) {
- panic("shared library " + lib + " does not end with " + sharedLibraryExtension)
+ if !strings.HasSuffix(file, flags.toolchain.ShlibSuffix()) {
+ panic("shared library " + lib + " does not end with " + flags.toolchain.ShlibSuffix())
}
libFlagsList = append(libFlagsList,
- "-l"+strings.TrimSuffix(strings.TrimPrefix(file, "lib"), sharedLibraryExtension))
+ "-l"+strings.TrimSuffix(strings.TrimPrefix(file, "lib"), flags.toolchain.ShlibSuffix()))
ldDirs = append(ldDirs, dir)
}
diff --git a/cc/cc.go b/cc/cc.go
index b1bc069b..00a09089 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -21,7 +21,6 @@ package cc
import (
"fmt"
"path/filepath"
- "runtime"
"strings"
"github.com/google/blueprint"
@@ -82,7 +81,6 @@ var (
"-Wno-unused",
"-Winit-self",
"-Wpointer-arith",
- "-fdiagnostics-color",
"-fdebug-prefix-map=/proc/self/cwd=",
// COMMON_RELEASE_CFLAGS
@@ -91,6 +89,8 @@ var (
}
deviceGlobalCflags = []string{
+ "-fdiagnostics-color",
+
// TARGET_ERROR_FLAGS
"-Werror=return-type",
"-Werror=non-virtual-dtor",
@@ -407,9 +407,10 @@ func (c *CCBase) ccModuleType() CCModuleType {
func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
arch := ctx.Arch()
hod := ctx.HostOrDevice()
- factory := toolchainFactories[hod][arch.ArchType]
+ ht := ctx.HostType()
+ factory := toolchainFactories[hod][ht][arch.ArchType]
if factory == nil {
- ctx.ModuleErrorf("Toolchain not found for %s arch %q", hod.String(), arch.String())
+ ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String())
return nil
}
return factory(arch)
@@ -512,6 +513,10 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
}
}
+ if !toolchain.ClangSupported() {
+ flags.Clang = false
+ }
+
instructionSet := c.Properties.Instruction_set
instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
if flags.Clang {
@@ -826,33 +831,52 @@ func (c *CCLinked) stl(ctx common.AndroidBaseContext) string {
}
}
- switch c.Properties.Stl {
- case "libc++", "libc++_static",
- "libstdc++":
- return c.Properties.Stl
- case "none":
- return ""
- case "":
- if c.static() {
- return "libc++_static"
- } else {
- return "libc++" // TODO: mingw needs libstdc++
+ if ctx.HostType() == common.Windows {
+ switch c.Properties.Stl {
+ case "libc++", "libc++_static", "libstdc++", "":
+ // libc++ is not supported on mingw
+ return "libstdc++"
+ case "none":
+ return ""
+ default:
+ ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
+ return ""
+ }
+ } else {
+ switch c.Properties.Stl {
+ case "libc++", "libc++_static",
+ "libstdc++":
+ return c.Properties.Stl
+ case "none":
+ return ""
+ case "":
+ if c.static() {
+ return "libc++_static"
+ } else {
+ return "libc++"
+ }
+ default:
+ ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
+ return ""
}
- default:
- ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
- return ""
}
}
-var hostDynamicGccLibs, hostStaticGccLibs []string
+var hostDynamicGccLibs, hostStaticGccLibs map[common.HostType][]string
func init() {
- if runtime.GOOS == "darwin" {
- hostDynamicGccLibs = []string{"-lc", "-lSystem"}
- hostStaticGccLibs = []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"}
- } else {
- hostDynamicGccLibs = []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"}
- hostStaticGccLibs = []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"}
+ hostDynamicGccLibs = map[common.HostType][]string{
+ common.Linux: []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
+ common.Darwin: []string{"-lc", "-lSystem"},
+ common.Windows: []string{"-lmsvcr110", "-lmingw32", "-lgcc", "-lmoldname",
+ "-lmingwex", "-lmsvcrt", "-ladvapi32", "-lshell32", "-luser32",
+ "-lkernel32", "-lmingw32", "-lgcc", "-lmoldname", "-lmingwex",
+ "-lmsvcrt"},
+ }
+ hostStaticGccLibs = map[common.HostType][]string{
+ common.Linux: []string{"-Wl,--start-group", "-lgcc", "-lgcc_eh", "-lc", "-Wl,--end-group"},
+ common.Darwin: []string{"NO_STATIC_HOST_BINARIES_ON_DARWIN"},
+ common.Windows: []string{"NO_STATIC_HOST_BINARIES_ON_WINDOWS"},
}
}
@@ -870,9 +894,9 @@ func (c *CCLinked) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
flags.LdFlags = append(flags.LdFlags, "-lm", "-lpthread")
if c.staticBinary() {
- flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
+ flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.HostType()]...)
} else {
- flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
+ flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.HostType()]...)
}
} else {
if ctx.Arch().ArchType == common.Arm {
@@ -900,9 +924,9 @@ func (c *CCLinked) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
if c.staticBinary() {
- flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
+ flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs[ctx.HostType()]...)
} else {
- flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
+ flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs[ctx.HostType()]...)
}
}
default:
@@ -1148,7 +1172,12 @@ func (c *CCLibrary) exportedFlags() []string {
func (c *CCLibrary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
flags = c.CCLinked.flags(ctx, flags)
- flags.CFlags = append(flags.CFlags, "-fPIC")
+ // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
+ // all code is position independent, and then those warnings get promoted to
+ // errors.
+ if ctx.HostType() != common.Windows {
+ flags.CFlags = append(flags.CFlags, "-fPIC")
+ }
if c.static() {
flags.CFlags = append(flags.CFlags, c.LibraryProperties.Static.Cflags...)
@@ -1172,13 +1201,13 @@ func (c *CCLibrary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlag
"-dynamiclib",
"-single_module",
//"-read_only_relocs suppress",
- "-install_name @rpath/"+libName+sharedLibraryExtension,
+ "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
)
} else {
flags.LdFlags = append(flags.LdFlags,
"-Wl,--gc-sections",
sharedFlag,
- "-Wl,-soname,"+libName+sharedLibraryExtension,
+ "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(),
)
}
}
@@ -1224,7 +1253,7 @@ func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
objFiles = append(objFiles, objFilesShared...)
- outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
+ outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+flags.Toolchain.ShlibSuffix())
var linkerDeps []string
@@ -1448,7 +1477,19 @@ func (c *CCBinary) ModifyProperties(ctx CCModuleContext) {
func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
flags = c.CCLinked.flags(ctx, flags)
- flags.CFlags = append(flags.CFlags, "-fpie")
+ if ctx.Host() {
+ flags.LdFlags = append(flags.LdFlags, "-pie")
+ if ctx.HostType() == common.Windows {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup")
+ }
+ }
+
+ // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
+ // all code is position independent, and then those warnings get promoted to
+ // errors.
+ if ctx.HostType() != common.Windows {
+ flags.CFlags = append(flags.CFlags, "-fpie")
+ }
if ctx.Device() {
if Bool(c.BinaryProperties.Static_executable) {
@@ -1495,7 +1536,7 @@ func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
"from static libs or set static_executable: true")
}
- outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
+ outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx)+flags.Toolchain.ExecutableSuffix())
c.out = outputFile
if c.BinaryProperties.Prefix_symbols != "" {
afterPrefixSymbols := outputFile
@@ -1843,7 +1884,7 @@ func (c *ndkPrebuiltLibrary) compileModule(ctx common.AndroidModuleContext, flag
includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
c.exportFlags = []string{common.JoinWithPrefix(includeDirs, "-isystem ")}
- c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, sharedLibraryExtension,
+ c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(),
c.Properties.Sdk_version)
}
@@ -1911,7 +1952,7 @@ func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CC
c.exportFlags = []string{includeDirsToFlags(includeDirs)}
libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
- libExt := sharedLibraryExtension
+ libExt := flags.Toolchain.ShlibSuffix()
if c.LibraryProperties.BuildStatic {
libExt = staticLibraryExtension
}
diff --git a/cc/mips64_device.go b/cc/mips64_device.go
index d792d005..e0b6a89f 100644
--- a/cc/mips64_device.go
+++ b/cc/mips64_device.go
@@ -195,5 +195,5 @@ func mips64ToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- registerToolchainFactory(common.Device, common.Mips64, mips64ToolchainFactory)
+ registerDeviceToolchainFactory(common.Mips64, mips64ToolchainFactory)
}
diff --git a/cc/mips_device.go b/cc/mips_device.go
index 52bc1ecf..c3372fe6 100644
--- a/cc/mips_device.go
+++ b/cc/mips_device.go
@@ -227,5 +227,5 @@ func mipsToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- registerToolchainFactory(common.Device, common.Mips, mipsToolchainFactory)
+ registerDeviceToolchainFactory(common.Mips, mipsToolchainFactory)
}
diff --git a/cc/toolchain.go b/cc/toolchain.go
index 71a89794..5e4d02ff 100644
--- a/cc/toolchain.go
+++ b/cc/toolchain.go
@@ -22,15 +22,23 @@ import (
type toolchainFactory func(arch common.Arch) Toolchain
-var toolchainFactories = map[common.HostOrDevice]map[common.ArchType]toolchainFactory{
- common.Host: make(map[common.ArchType]toolchainFactory),
- common.Device: make(map[common.ArchType]toolchainFactory),
+var toolchainFactories = map[common.HostOrDevice]map[common.HostType]map[common.ArchType]toolchainFactory{
+ common.Host: map[common.HostType]map[common.ArchType]toolchainFactory{
+ common.Linux: make(map[common.ArchType]toolchainFactory),
+ common.Darwin: make(map[common.ArchType]toolchainFactory),
+ common.Windows: make(map[common.ArchType]toolchainFactory),
+ },
+ common.Device: map[common.HostType]map[common.ArchType]toolchainFactory{
+ common.NoHostType: make(map[common.ArchType]toolchainFactory),
+ },
}
-func registerToolchainFactory(hod common.HostOrDevice, arch common.ArchType,
- factory toolchainFactory) {
+func registerDeviceToolchainFactory(arch common.ArchType, factory toolchainFactory) {
+ toolchainFactories[common.Device][common.NoHostType][arch] = factory
+}
- toolchainFactories[hod][arch] = factory
+func registerHostToolchainFactory(ht common.HostType, arch common.ArchType, factory toolchainFactory) {
+ toolchainFactories[common.Host][ht][arch] = factory
}
type Toolchain interface {
@@ -47,6 +55,7 @@ type Toolchain interface {
IncludeFlags() string
InstructionSetFlags(string) (string, error)
+ ClangSupported() bool
ClangTriple() string
ToolchainClangCflags() string
ClangCflags() string
@@ -55,6 +64,9 @@ type Toolchain interface {
ClangInstructionSetFlags(string) (string, error)
Is64Bit() bool
+
+ ShlibSuffix() string
+ ExecutableSuffix() string
}
type toolchainBase struct {
@@ -86,6 +98,18 @@ func (toolchainBase) ToolchainClangCflags() string {
return ""
}
+func (toolchainBase) ClangSupported() bool {
+ return true
+}
+
+func (toolchainBase) ShlibSuffix() string {
+ return ".so"
+}
+
+func (toolchainBase) ExecutableSuffix() string {
+ return ""
+}
+
type toolchain64Bit struct {
toolchainBase
}
diff --git a/cc/x86_64_device.go b/cc/x86_64_device.go
index bd68ca50..728442cc 100644
--- a/cc/x86_64_device.go
+++ b/cc/x86_64_device.go
@@ -256,5 +256,5 @@ func x86_64ToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- registerToolchainFactory(common.Device, common.X86_64, x86_64ToolchainFactory)
+ registerDeviceToolchainFactory(common.X86_64, x86_64ToolchainFactory)
}
diff --git a/cc/x86_darwin_host.go b/cc/x86_darwin_host.go
index 4195dae3..9ca03bac 100644
--- a/cc/x86_darwin_host.go
+++ b/cc/x86_darwin_host.go
@@ -1,7 +1,6 @@
package cc
import (
- "runtime"
"strings"
"android/soong/common"
@@ -12,6 +11,8 @@ var (
"-fno-exceptions", // from build/core/combo/select.mk
"-Wno-multichar", // from build/core/combo/select.mk
+ "-fdiagnostics-color",
+
"-fPIC",
"-funwind-tables",
@@ -195,6 +196,10 @@ func (t *toolchainDarwinX8664) ClangLdflags() string {
return "${darwinClangLdflags} ${darwinX8664ClangLdflags}"
}
+func (t *toolchainDarwin) ShlibSuffix() string {
+ return ".dylib"
+}
+
var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{}
var toolchainDarwinX8664Singleton Toolchain = &toolchainDarwinX8664{}
@@ -207,8 +212,6 @@ func darwinX8664ToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- if runtime.GOOS == "darwin" {
- registerToolchainFactory(common.Host, common.X86, darwinX86ToolchainFactory)
- registerToolchainFactory(common.Host, common.X86_64, darwinX8664ToolchainFactory)
- }
+ registerHostToolchainFactory(common.Darwin, common.X86, darwinX86ToolchainFactory)
+ registerHostToolchainFactory(common.Darwin, common.X86_64, darwinX8664ToolchainFactory)
}
diff --git a/cc/x86_device.go b/cc/x86_device.go
index df0c0ffa..8543240c 100644
--- a/cc/x86_device.go
+++ b/cc/x86_device.go
@@ -258,5 +258,5 @@ func x86ToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- registerToolchainFactory(common.Device, common.X86, x86ToolchainFactory)
+ registerDeviceToolchainFactory(common.X86, x86ToolchainFactory)
}
diff --git a/cc/x86_linux_host.go b/cc/x86_linux_host.go
index f5444760..09a08033 100644
--- a/cc/x86_linux_host.go
+++ b/cc/x86_linux_host.go
@@ -1,7 +1,6 @@
package cc
import (
- "runtime"
"strings"
"android/soong/common"
@@ -12,6 +11,8 @@ var (
"-fno-exceptions", // from build/core/combo/select.mk
"-Wno-multichar", // from build/core/combo/select.mk
+ "-fdiagnostics-color",
+
"-Wa,--noexecstack",
"-fPIC",
@@ -233,8 +234,6 @@ func linuxX8664ToolchainFactory(arch common.Arch) Toolchain {
}
func init() {
- if runtime.GOOS == "linux" {
- registerToolchainFactory(common.Host, common.X86, linuxX86ToolchainFactory)
- registerToolchainFactory(common.Host, common.X86_64, linuxX8664ToolchainFactory)
- }
+ registerHostToolchainFactory(common.Linux, common.X86, linuxX86ToolchainFactory)
+ registerHostToolchainFactory(common.Linux, common.X86_64, linuxX8664ToolchainFactory)
}
diff --git a/cc/x86_windows_host.go b/cc/x86_windows_host.go
new file mode 100644
index 00000000..70ce74d5
--- /dev/null
+++ b/cc/x86_windows_host.go
@@ -0,0 +1,150 @@
+// Copyright 2015 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 cc
+
+import (
+ "strings"
+
+ "android/soong/common"
+)
+
+var (
+ windowsCflags = []string{
+ "-fno-exceptions", // from build/core/combo/select.mk
+ "-Wno-multichar", // from build/core/combo/select.mk
+
+ "-DUSE_MINGW",
+ "-DWIN32_LEAN_AND_MEAN",
+ "-Wno-unused-parameter",
+ "-m32",
+
+ // Workaround differences in inttypes.h between host and target.
+ //See bug 12708004.
+ "-D__STDC_FORMAT_MACROS",
+ "-D__STDC_CONSTANT_MACROS",
+
+ // Use C99-compliant printf functions (%zd).
+ "-D__USE_MINGW_ANSI_STDIO=1",
+ // Admit to using >= Win2K. Both are needed because of <_mingw.h>.
+ "-D_WIN32_WINNT=0x0500",
+ "-DWINVER=0x0500",
+ // Get 64-bit off_t and related functions.
+ "-D_FILE_OFFSET_BITS=64",
+
+ // HOST_RELEASE_CFLAGS
+ "-O2", // from build/core/combo/select.mk
+ "-g", // from build/core/combo/select.mk
+ "-fno-strict-aliasing", // from build/core/combo/select.mk
+ }
+
+ windowsIncludeFlags = []string{
+ "-I${windowsGccRoot}/${windowsGccTriple}/include",
+ "-I${windowsGccRoot}/lib/gcc/${windowsGccTriple}/4.8.3/include",
+ }
+
+ windowsLdflags = []string{
+ "-m32",
+ "-L${windowsGccRoot}/${windowsGccTriple}",
+ "--enable-stdcall-fixup",
+ }
+)
+
+func init() {
+ pctx.StaticVariable("windowsGccVersion", "4.8")
+
+ pctx.StaticVariable("windowsGccRoot",
+ "${SrcDir}/prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${windowsGccVersion}")
+
+ pctx.StaticVariable("windowsGccTriple", "x86_64-w64-mingw32")
+
+ pctx.StaticVariable("windowsCflags", strings.Join(windowsCflags, " "))
+ pctx.StaticVariable("windowsLdflags", strings.Join(windowsLdflags, " "))
+}
+
+type toolchainWindows struct {
+ toolchain32Bit
+
+ cFlags, ldFlags string
+}
+
+func (t *toolchainWindows) Name() string {
+ return "x86"
+}
+
+func (t *toolchainWindows) GccRoot() string {
+ return "${windowsGccRoot}"
+}
+
+func (t *toolchainWindows) GccTriple() string {
+ return "${windowsGccTriple}"
+}
+
+func (t *toolchainWindows) GccVersion() string {
+ return "${windowsGccVersion}"
+}
+
+func (t *toolchainWindows) Cflags() string {
+ return "${windowsCflags}"
+}
+
+func (t *toolchainWindows) Cppflags() string {
+ return ""
+}
+
+func (t *toolchainWindows) Ldflags() string {
+ return "${windowsLdflags}"
+}
+
+func (t *toolchainWindows) IncludeFlags() string {
+ return ""
+}
+
+func (t *toolchainWindows) ClangSupported() bool {
+ return false
+}
+
+func (t *toolchainWindows) ClangTriple() string {
+ panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ClangCflags() string {
+ panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ClangCppflags() string {
+ panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ClangLdflags() string {
+ panic("Clang is not supported under mingw")
+}
+
+func (t *toolchainWindows) ShlibSuffix() string {
+ return ".dll"
+}
+
+func (t *toolchainWindows) ExecutableSuffix() string {
+ return ".exe"
+}
+
+var toolchainWindowsSingleton Toolchain = &toolchainWindows{}
+
+func windowsToolchainFactory(arch common.Arch) Toolchain {
+ return toolchainWindowsSingleton
+}
+
+func init() {
+ registerHostToolchainFactory(common.Windows, common.X86, windowsToolchainFactory)
+}
diff --git a/common/arch.go b/common/arch.go
index 8ac52e66..4cddc00e 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -29,6 +29,7 @@ func init() {
RegisterTopDownMutator("defaults", defaultsMutator)
RegisterBottomUpMutator("host_or_device", HostOrDeviceMutator)
+ RegisterBottomUpMutator("host_type", HostTypeMutator)
RegisterBottomUpMutator("arch", ArchMutator)
}
@@ -261,6 +262,8 @@ type archProperties struct {
Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
// Properties for module variants being built to run on windows hosts
Windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
+ // Properties for module variants being built to run on windows x86 hosts
+ Windows_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
// Properties for module variants being built to run on linux or darwin hosts
Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
}
@@ -383,6 +386,52 @@ var hostOrDeviceName = map[HostOrDevice]string{
Host: "host",
}
+type HostType int
+
+const (
+ NoHostType HostType = iota
+ Linux
+ Darwin
+ Windows
+)
+
+func CurrentHostType() HostType {
+ switch runtime.GOOS {
+ case "linux":
+ return Linux
+ case "darwin":
+ return Darwin
+ default:
+ panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
+ }
+}
+
+func (ht HostType) String() string {
+ switch ht {
+ case Linux:
+ return "linux"
+ case Darwin:
+ return "darwin"
+ case Windows:
+ return "windows"
+ default:
+ panic(fmt.Sprintf("unexpected HostType value %d", ht))
+ }
+}
+
+func (ht HostType) Field() string {
+ switch ht {
+ case Linux:
+ return "Linux"
+ case Darwin:
+ return "Darwin"
+ case Windows:
+ return "Windows"
+ default:
+ panic(fmt.Sprintf("unexpected HostType value %d", ht))
+ }
+}
+
var (
commonArch = Arch{
ArchType: Common,
@@ -421,6 +470,34 @@ func HostOrDeviceMutator(mctx AndroidBottomUpMutatorContext) {
}
}
+func HostTypeMutator(mctx AndroidBottomUpMutatorContext) {
+ var module AndroidModule
+ var ok bool
+ if module, ok = mctx.Module().(AndroidModule); !ok {
+ return
+ }
+
+ if !module.base().HostSupported() || !module.base().HostOrDevice().Host() {
+ return
+ }
+
+ buildTypes, err := decodeHostTypesProductVariables(mctx.Config().(Config).ProductVariables)
+ if err != nil {
+ mctx.ModuleErrorf("%s", err.Error())
+ return
+ }
+
+ typeNames := []string{}
+ for _, ht := range buildTypes {
+ typeNames = append(typeNames, ht.String())
+ }
+
+ modules := mctx.CreateVariations(typeNames...)
+ for i, m := range modules {
+ m.(AndroidModule).base().SetHostType(buildTypes[i])
+ }
+}
+
func ArchMutator(mctx AndroidBottomUpMutatorContext) {
var module AndroidModule
var ok bool
@@ -437,7 +514,7 @@ func ArchMutator(mctx AndroidBottomUpMutatorContext) {
multilib := module.base().commonProperties.Compile_multilib
if module.base().HostSupported() && module.base().HostOrDevice().Host() {
- hostModuleArches, err := decodeMultilib(multilib, hostArches)
+ hostModuleArches, err := decodeMultilib(multilib, hostArches[module.base().HostType()])
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
@@ -560,6 +637,7 @@ func (a *AndroidModuleBase) appendProperties(ctx AndroidBottomUpMutatorContext,
func (a *AndroidModuleBase) setArchProperties(ctx AndroidBottomUpMutatorContext) {
arch := a.commonProperties.CompileArch
hod := a.commonProperties.CompileHostOrDevice
+ ht := a.commonProperties.CompileHostType
if arch.ArchType == Common {
return
@@ -654,30 +732,21 @@ func (a *AndroidModuleBase) setArchProperties(ctx AndroidBottomUpMutatorContext)
// key: value,
// },
// },
- var osList = []struct {
- goos string
- field string
- }{
- {"darwin", "Darwin"},
- {"linux", "Linux"},
- {"windows", "Windows"},
- }
-
if hod.Host() {
- for _, v := range osList {
- if v.goos == runtime.GOOS {
- field := v.field
- prefix := "target." + v.goos
- a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
- t := arch.ArchType
- field = v.field + "_" + t.Name
- prefix = "target." + v.goos + "_" + t.Name
- a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
- }
- }
- field := "Not_windows"
- prefix := "target.not_windows"
+ field := ht.Field()
+ prefix := "target." + ht.String()
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
+
+ t := arch.ArchType
+ field = ht.Field() + "_" + t.Name
+ prefix = "target." + ht.String() + "_" + t.Name
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
+
+ if ht != Windows {
+ field := "Not_windows"
+ prefix := "target.not_windows"
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
+ }
}
// Handle 64-bit device properties in the form:
@@ -742,8 +811,24 @@ func forEachInterface(v reflect.Value, f func(reflect.Value)) {
}
}
+// Get a list of HostTypes from the product variables
+func decodeHostTypesProductVariables(variables productVariables) ([]HostType, error) {
+ ret := []HostType{CurrentHostType()}
+
+ if variables.CrossHost != nil && *variables.CrossHost != "" {
+ switch *variables.CrossHost {
+ case "windows":
+ ret = append(ret, Windows)
+ default:
+ return nil, fmt.Errorf("Unsupported secondary host: %s", *variables.CrossHost)
+ }
+ }
+
+ return ret, nil
+}
+
// Convert the arch product variables into a list of host and device Arch structs
-func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, error) {
+func decodeArchProductVariables(variables productVariables) (map[HostType][]Arch, []Arch, error) {
if variables.HostArch == nil {
return nil, nil, fmt.Errorf("No host primary architecture set")
}
@@ -763,6 +848,38 @@ func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, err
hostArches = append(hostArches, hostSecondaryArch)
}
+ hostTypeArches := map[HostType][]Arch{
+ CurrentHostType(): hostArches,
+ }
+
+ if variables.CrossHost != nil && *variables.CrossHost != "" {
+ if variables.CrossHostArch == nil || *variables.CrossHostArch == "" {
+ return nil, nil, fmt.Errorf("No cross-host primary architecture set")
+ }
+
+ crossHostArch, err := decodeArch(*variables.CrossHostArch, nil, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ crossHostArches := []Arch{crossHostArch}
+
+ if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
+ crossHostSecondaryArch, err := decodeArch(*variables.CrossHostSecondaryArch, nil, nil, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+ crossHostArches = append(crossHostArches, crossHostSecondaryArch)
+ }
+
+ switch *variables.CrossHost {
+ case "windows":
+ hostTypeArches[Windows] = crossHostArches
+ default:
+ return nil, nil, fmt.Errorf("Unsupported cross-host: %s", *variables.CrossHost)
+ }
+ }
+
if variables.DeviceArch == nil {
return nil, nil, fmt.Errorf("No device primary architecture set")
}
@@ -785,7 +902,7 @@ func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, err
deviceArches = append(deviceArches, deviceSecondaryArch)
}
- return hostArches, deviceArches, nil
+ return hostTypeArches, deviceArches, nil
}
// Convert a set of strings from product variables into a single Arch struct
diff --git a/common/module.go b/common/module.go
index b64342f6..7bb21a25 100644
--- a/common/module.go
+++ b/common/module.go
@@ -17,7 +17,6 @@ package common
import (
"android/soong"
"path/filepath"
- "runtime"
"android/soong/glob"
@@ -37,6 +36,7 @@ var (
type androidBaseContext interface {
Arch() Arch
HostOrDevice() HostOrDevice
+ HostType() HostType
Host() bool
Device() bool
Darwin() bool
@@ -88,6 +88,9 @@ type commonProperties struct {
// Set by HostOrDeviceMutator
CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
+ // Set by HostTypeMutator
+ CompileHostType HostType `blueprint:"mutated"`
+
// Set by ArchMutator
CompileArch Arch `blueprint:"mutated"`
@@ -208,6 +211,10 @@ func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
a.commonProperties.CompileHostOrDevice = hod
}
+func (a *AndroidModuleBase) SetHostType(ht HostType) {
+ a.commonProperties.CompileHostType = ht
+}
+
func (a *AndroidModuleBase) SetArch(arch Arch) {
a.commonProperties.CompileArch = arch
}
@@ -216,6 +223,10 @@ func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
return a.commonProperties.CompileHostOrDevice
}
+func (a *AndroidModuleBase) HostType() HostType {
+ return a.commonProperties.CompileHostType
+}
+
func (a *AndroidModuleBase) HostSupported() bool {
return a.commonProperties.HostOrDeviceSupported == HostSupported ||
a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
@@ -229,6 +240,12 @@ func (a *AndroidModuleBase) DeviceSupported() bool {
}
func (a *AndroidModuleBase) Disabled() bool {
+ if a.commonProperties.CompileHostOrDevice == Host &&
+ a.commonProperties.CompileHostType == Windows &&
+ a.commonProperties.Disabled == nil {
+
+ return true
+ }
return proptools.Bool(a.commonProperties.Disabled)
}
@@ -308,6 +325,7 @@ func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleCo
return androidBaseContextImpl{
arch: a.commonProperties.CompileArch,
hod: a.commonProperties.CompileHostOrDevice,
+ ht: a.commonProperties.CompileHostType,
config: ctx.Config().(Config),
}
}
@@ -320,7 +338,7 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
installFiles: a.installFiles,
}
- if proptools.Bool(a.commonProperties.Disabled) {
+ if a.Disabled() {
return
}
@@ -341,6 +359,7 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
type androidBaseContextImpl struct {
arch Arch
hod HostOrDevice
+ ht HostType
debug bool
config Config
}
@@ -366,6 +385,10 @@ func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
return a.hod
}
+func (a *androidBaseContextImpl) HostType() HostType {
+ return a.ht
+}
+
func (a *androidBaseContextImpl) Host() bool {
return a.hod.Host()
}
@@ -375,7 +398,7 @@ func (a *androidBaseContextImpl) Device() bool {
}
func (a *androidBaseContextImpl) Darwin() bool {
- return a.hod.Host() && runtime.GOOS == "darwin"
+ return a.hod.Host() && a.ht == Darwin
}
func (a *androidBaseContextImpl) Debug() bool {
@@ -396,7 +419,12 @@ func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string
fullInstallPath = filepath.Join(config.DeviceOut(), "system",
installPath, name)
} else {
- fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
+ // TODO
+ if a.ht == Windows {
+ fullInstallPath = filepath.Join(config.BuildDir(), "host", "windows-x86", installPath, name)
+ } else {
+ fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
+ }
}
deps = append(deps, a.installDeps...)
diff --git a/common/variable.go b/common/variable.go
index 9a5998f7..5b9092f3 100644
--- a/common/variable.go
+++ b/common/variable.go
@@ -17,6 +17,7 @@ package common
import (
"fmt"
"reflect"
+ "runtime"
"strings"
"github.com/google/blueprint/proptools"
@@ -69,6 +70,10 @@ type productVariables struct {
HostArch *string `json:",omitempty"`
HostSecondaryArch *string `json:",omitempty"`
+
+ CrossHost *string `json:",omitempty"`
+ CrossHostArch *string `json:",omitempty"`
+ CrossHostSecondaryArch *string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
@@ -99,6 +104,11 @@ func (v *productVariables) SetDefaultConfig() {
DeviceSecondaryCpuVariant: stringPtr("denver"),
DeviceSecondaryAbi: &[]string{"armeabi-v7a"},
}
+
+ if runtime.GOOS == "linux" {
+ v.CrossHost = stringPtr("windows")
+ v.CrossHostArch = stringPtr("x86")
+ }
}
func variableMutator(mctx AndroidBottomUpMutatorContext) {
diff --git a/genrule/genrule.go b/genrule/genrule.go
index fb0dafcf..76b4f16a 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -88,8 +88,10 @@ func (g *generator) GeneratedSourceFiles() []string {
func genruleDepsMutator(ctx common.AndroidBottomUpMutatorContext) {
if g, ok := ctx.Module().(*generator); ok {
if g.properties.Tool != "" {
- ctx.AddFarVariationDependencies([]blueprint.Variation{{"hostordevice", common.Host.String()}},
- g.properties.Tool)
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {"host_or_device", common.Host.String()},
+ {"host_type", common.CurrentHostType().String()},
+ }, g.properties.Tool)
}
}
}