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
diff --git a/cc/cc.go b/cc/cc.go
index b1bc069..00a0908 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -21,7 +21,6 @@
import (
"fmt"
"path/filepath"
- "runtime"
"strings"
"github.com/google/blueprint"
@@ -82,7 +81,6 @@
"-Wno-unused",
"-Winit-self",
"-Wpointer-arith",
- "-fdiagnostics-color",
"-fdebug-prefix-map=/proc/self/cwd=",
// COMMON_RELEASE_CFLAGS
@@ -91,6 +89,8 @@
}
deviceGlobalCflags = []string{
+ "-fdiagnostics-color",
+
// TARGET_ERROR_FLAGS
"-Werror=return-type",
"-Werror=non-virtual-dtor",
@@ -407,9 +407,10 @@
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 @@
}
}
+ if !toolchain.ClangSupported() {
+ flags.Clang = false
+ }
+
instructionSet := c.Properties.Instruction_set
instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
if flags.Clang {
@@ -826,33 +831,52 @@
}
}
- 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 ""
}
- 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 ""
+ }
}
}
-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 @@
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 @@
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) 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 @@
"-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 @@
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) 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 @@
"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 @@
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 @@
c.exportFlags = []string{includeDirsToFlags(includeDirs)}
libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
- libExt := sharedLibraryExtension
+ libExt := flags.Toolchain.ShlibSuffix()
if c.LibraryProperties.BuildStatic {
libExt = staticLibraryExtension
}