aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2015-03-18 23:38:50 -0700
committerDan Albert <danalbert@google.com>2015-03-26 21:58:12 -0700
commitbe96168ee3f9d45805758354563981a892253d1c (patch)
tree0b7a824abfcc8080b0ad97ff7358383a7c3cba27
parent68f55102dadc880e2b57c669415771395ac0c3b0 (diff)
downloadbuild_soong-be96168ee3f9d45805758354563981a892253d1c.tar.gz
build_soong-be96168ee3f9d45805758354563981a892253d1c.tar.bz2
build_soong-be96168ee3f9d45805758354563981a892253d1c.zip
Add support for building NDK modules.
Change-Id: I2c5ede530e40a635e26ae45950580ef450e7dcc6
-rw-r--r--androidmk/cmd/androidmk/android.go16
-rw-r--r--cc/arm64_device.go8
-rw-r--r--cc/arm_device.go8
-rw-r--r--cc/cc.go184
-rw-r--r--cc/toolchain.go3
-rw-r--r--cc/x86_linux_host.go12
-rw-r--r--cmd/soong_build/main.go3
-rw-r--r--common/arch.go3
-rw-r--r--root.bp1
9 files changed, 224 insertions, 14 deletions
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index b79e821f..fa25a9f0 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -17,13 +17,15 @@ const (
)
var stringProperties = map[string]string{
- "LOCAL_MODULE": "name",
- "LOCAL_MODULE_STEM": "stem",
- "LOCAL_MODULE_CLASS": "class",
- "LOCAL_CXX_STL": "stl",
- "LOCAL_STRIP_MODULE": "strip",
- "LOCAL_MULTILIB": "compile_multilib",
- "LOCAL_ARM_MODE_HACK": "instruction_set",
+ "LOCAL_MODULE": "name",
+ "LOCAL_MODULE_STEM": "stem",
+ "LOCAL_MODULE_CLASS": "class",
+ "LOCAL_CXX_STL": "stl",
+ "LOCAL_STRIP_MODULE": "strip",
+ "LOCAL_MULTILIB": "compile_multilib",
+ "LOCAL_ARM_MODE_HACK": "instruction_set",
+ "LOCAL_SDK_VERSION": "sdk_version",
+ "LOCAL_NDK_STL_VARIANT": "stl",
}
var listProperties = map[string]string{
diff --git a/cc/arm64_device.go b/cc/arm64_device.go
index ac0d94a4..309d01da 100644
--- a/cc/arm64_device.go
+++ b/cc/arm64_device.go
@@ -88,6 +88,10 @@ type toolchainArm64 struct {
var toolchainArm64Singleton = &toolchainArm64{}
+func (t *toolchainArm64) Name() string {
+ return "arm64"
+}
+
func (t *toolchainArm64) GccRoot() string {
return "${arm64GccRoot}"
}
@@ -96,6 +100,10 @@ func (t *toolchainArm64) GccTriple() string {
return "${arm64GccTriple}"
}
+func (t *toolchainArm64) GccVersion() string {
+ return "${arm64GccVersion}"
+}
+
func (t *toolchainArm64) Cflags() string {
return "${arm64Cflags} ${arm64IncludeFlags}"
}
diff --git a/cc/arm_device.go b/cc/arm_device.go
index e7365098..bc59ab82 100644
--- a/cc/arm_device.go
+++ b/cc/arm_device.go
@@ -232,6 +232,10 @@ type toolchainArm struct {
cflags, ldflags, clangCflags string
}
+func (t *toolchainArm) Name() string {
+ return "arm"
+}
+
func (t *toolchainArm) GccRoot() string {
return "${armGccRoot}"
}
@@ -240,6 +244,10 @@ func (t *toolchainArm) GccTriple() string {
return "${armGccTriple}"
}
+func (t *toolchainArm) GccVersion() string {
+ return "${armGccVersion}"
+}
+
func (t *toolchainArm) Cflags() string {
return t.cflags
}
diff --git a/cc/cc.go b/cc/cc.go
index 2c729fe3..2583c866 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -146,7 +146,7 @@ type ccProperties struct {
// export_include_dirs: list of directories relative to the Blueprints file that will
// be added to the include path using -I for any module that links against this module
- Export_include_dirs []string
+ Export_include_dirs []string `android:"arch_variant"`
// clang_cflags: list of module-specific flags that will be used for C and C++ compiles when
// compiling with clang
@@ -350,6 +350,23 @@ func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
return factory(arch.ArchVariant, arch.CpuVariant)
}
+func addNdkStlDepNames(ctx common.AndroidBaseContext, stl string, depNames CCDeps) CCDeps {
+ if stl == "ndk_system" {
+ // TODO: Make a system STL prebuilt for the NDK.
+ // The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
+ // its own includes. The includes are handled in ccBase.Flags().
+ return depNames
+ }
+
+ if strings.HasSuffix(stl, "_static") {
+ depNames.StaticLibs = append(depNames.StaticLibs, stl)
+ } else {
+ depNames.SharedLibs = append(depNames.SharedLibs, stl)
+ }
+
+ return depNames
+}
+
func (c *ccBase) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.properties.Whole_static_libs...)
depNames.StaticLibs = append(depNames.StaticLibs, c.properties.Static_libs...)
@@ -369,6 +386,14 @@ func (c *ccBase) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps
depNames.SharedLibs = append(depNames.SharedLibs, "libstdc++", "libstlport")
case "stlport_static":
depNames.StaticLibs = append(depNames.StaticLibs, "libstdc++", "libstlport_static")
+ case "":
+ // None or error.
+ default:
+ if !strings.HasPrefix(stl, "ndk_") {
+ panic("unexpected case")
+ }
+
+ depNames = addNdkStlDepNames(ctx, stl, depNames)
}
return depNames
@@ -533,6 +558,14 @@ func (c *ccBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
}
func (c *ccBase) stl(ctx common.AndroidBaseContext) string {
+ if c.properties.Sdk_version != "" {
+ stl := c.properties.Stl
+ if stl == "" {
+ return "ndk_system"
+ }
+ return "ndk_lib" + stl
+ }
+
switch c.properties.Stl {
case "libc++", "libc++_static",
"stlport", "stlport_static",
@@ -542,8 +575,6 @@ func (c *ccBase) stl(ctx common.AndroidBaseContext) string {
return ""
case "":
return "libc++" // TODO: mingw needs libstdc++
- case "ndk":
- panic("TODO: stl: ndk")
default:
ctx.ModuleErrorf("stl: %q is not a supported STL", c.properties.Stl)
return ""
@@ -572,8 +603,6 @@ func (c *ccBase) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
"${SrcDir}/bionic/libstdc++/include",
"${SrcDir}/bionic")
}
- case "ndk":
- panic("TODO")
case "libstdc++":
// Using bionic's basic libstdc++. Not actually an STL. Only around until the
// tree is in good enough shape to not need it.
@@ -581,14 +610,19 @@ func (c *ccBase) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
if ctx.Device() {
flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/bionic/libstdc++/include")
}
+ case "ndk_system":
+ ndkSrcRoot := ctx.Config().(Config).SrcDir() + "/prebuilts/ndk/current/sources/"
+ flags.IncludeDirs = append(flags.IncludeDirs, ndkSrcRoot + "cxx-stl/system/include")
+ case "ndk_c++_shared", "ndk_c++_static":
+ // TODO(danalbert): This really shouldn't be here...
+ flags.CppFlags = append(flags.CppFlags, "-std=c++11")
case "":
+ // None or error.
if ctx.Host() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
flags.LdLibs = append(flags.LdLibs, "-lc", "-lm")
}
- default:
- panic(fmt.Errorf("Unknown stl: %q", stl))
}
return flags
@@ -766,6 +800,17 @@ func (c *ccDynamic) systemSharedLibs(ctx common.AndroidBaseContext) []string {
if ctx.Host() {
return []string{}
+ } else if c.properties.Sdk_version != "" {
+ version := c.properties.Sdk_version
+ libs := []string{
+ "ndk_libc." + version,
+ "ndk_libm." + version,
+ }
+
+ if c.properties.Sdk_version != "" && c.stl(ctx) == "ndk_system" {
+ libs = append([]string{"libstdc++"}, libs...)
+ }
+ return libs
} else {
return []string{"libc", "libm"}
}
@@ -1295,6 +1340,131 @@ func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags
// Toolchain libraries do not get installed.
}
+// NDK prebuilt libraries.
+//
+// These differ from regular prebuilts in that they aren't stripped and usually aren't installed
+// either (with the exception of the shared STLs, which are installed to the app's directory rather
+// than to the system image).
+
+func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) string {
+ return fmt.Sprintf("%s/prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib",
+ ctx.Config().(Config).SrcDir(), version, toolchain.Name())
+}
+
+type ndkPrebuiltLibrary struct {
+ CCLibrary
+}
+
+func (*ndkPrebuiltLibrary) AndroidDynamicDependencies(
+ ctx common.AndroidDynamicDependerModuleContext) []string {
+
+ // NDK libraries can't have any dependencies
+ return nil
+}
+
+func (*ndkPrebuiltLibrary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
+ // NDK libraries can't have any dependencies
+ return CCDeps{}
+}
+
+func NdkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) {
+ module := &ndkPrebuiltLibrary{}
+ module.LibraryProperties.BuildShared = true
+ return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
+}
+
+func (c *ndkPrebuiltLibrary) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
+ deps CCDeps, objFiles []string) {
+ // A null build step, but it sets up the output path.
+ if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
+ ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
+ }
+
+ c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
+ common.ModuleSrcDir(ctx))
+
+ // NDK prebuilt libraries are named like: ndk_LIBNAME.SDK_VERSION.
+ // We want to translate to just LIBNAME.
+ libName := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
+ libDir := getNdkLibDir(ctx, flags.Toolchain, c.properties.Sdk_version)
+ c.out = filepath.Join(libDir, libName + sharedLibraryExtension)
+}
+
+func (c *ndkPrebuiltLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
+ // Toolchain libraries do not get installed.
+}
+
+// The NDK STLs are slightly different from the prebuilt system libraries:
+// * Are not specific to each platform version.
+// * The libraries are not in a predictable location for each STL.
+
+type ndkPrebuiltStl struct {
+ ndkPrebuiltLibrary
+}
+
+type ndkPrebuiltStaticStl struct {
+ ndkPrebuiltStl
+}
+
+type ndkPrebuiltSharedStl struct {
+ ndkPrebuiltStl
+}
+
+func NdkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) {
+ module := &ndkPrebuiltSharedStl{}
+ module.LibraryProperties.BuildShared = true
+ return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
+}
+
+func NdkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) {
+ module := &ndkPrebuiltStaticStl{}
+ module.LibraryProperties.BuildStatic = true
+ return NewCCLibrary(&module.CCLibrary, module, common.DeviceSupported)
+}
+
+func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) string {
+ gccVersion := toolchain.GccVersion()
+ var libDir string
+ switch stl {
+ case "libstlport":
+ libDir = "cxx-stl/stlport/libs"
+ case "libc++":
+ libDir = "cxx-stl/llvm-libc++/libs"
+ case "libgnustl":
+ libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion)
+ }
+
+ if libDir != "" {
+ ndkSrcRoot := ctx.Config().(Config).SrcDir() + "/prebuilts/ndk/current/sources"
+ return fmt.Sprintf("%s/%s/%s", ndkSrcRoot, libDir, ctx.Arch().Abi)
+ }
+
+ ctx.ModuleErrorf("Unknown NDK STL: %s", stl)
+ return ""
+}
+
+func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CCFlags,
+ deps CCDeps, objFiles []string) {
+ // A null build step, but it sets up the output path.
+ if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") {
+ ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name")
+ }
+
+ c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
+ common.ModuleSrcDir(ctx))
+
+ libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_")
+ libExt := sharedLibraryExtension
+ if c.LibraryProperties.BuildStatic {
+ libExt = staticLibraryExtension
+ }
+
+ stlName := strings.TrimSuffix(libName, "_shared")
+ stlName = strings.TrimSuffix(stlName, "_static")
+ libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName)
+ c.out = libDir + "/" + libName + libExt
+}
+
func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
if c, ok := mctx.Module().(ccLibraryInterface); ok {
var modules []blueprint.Module
diff --git a/cc/toolchain.go b/cc/toolchain.go
index e4d23bdd..d188845d 100644
--- a/cc/toolchain.go
+++ b/cc/toolchain.go
@@ -34,8 +34,11 @@ func registerToolchainFactory(hod common.HostOrDevice, arch common.ArchType,
}
type Toolchain interface {
+ Name() string
+
GccRoot() string
GccTriple() string
+ GccVersion() string
Cflags() string
Cppflags() string
Ldflags() string
diff --git a/cc/x86_linux_host.go b/cc/x86_linux_host.go
index 795620b3..94b4a721 100644
--- a/cc/x86_linux_host.go
+++ b/cc/x86_linux_host.go
@@ -148,6 +148,14 @@ type toolchainLinuxX8664 struct {
toolchainLinux
}
+func (t *toolchainLinuxX86) Name() string {
+ return "x86"
+}
+
+func (t *toolchainLinuxX8664) Name() string {
+ return "x86_64"
+}
+
func (t *toolchainLinux) GccRoot() string {
return "${linuxGccRoot}"
}
@@ -156,6 +164,10 @@ func (t *toolchainLinux) GccTriple() string {
return "${linuxGccTriple}"
}
+func (t *toolchainLinux) GccVersion() string {
+ return "${linuxGccVersion}"
+}
+
func (t *toolchainLinuxX86) Cflags() string {
return "${linuxCflags} ${linuxX86Cflags}"
}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index cb579e9c..c1f8243a 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -47,6 +47,9 @@ func main() {
ctx.RegisterModuleType("cc_test", cc.CCTestFactory)
ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+ ctx.RegisterModuleType("ndk_prebuilt_library", cc.NdkPrebuiltLibraryFactory)
+ ctx.RegisterModuleType("ndk_prebuilt_static_stl", cc.NdkPrebuiltStaticStlFactory)
+ ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory)
ctx.RegisterModuleType("cc_library_host_static", cc.CCLibraryHostStaticFactory)
ctx.RegisterModuleType("cc_library_host_shared", cc.CCLibraryHostSharedFactory)
diff --git a/common/arch.go b/common/arch.go
index a43aa728..02212ade 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -117,6 +117,7 @@ type Arch struct {
ArchType ArchType
ArchVariant string
CpuVariant string
+ Abi string
}
func (a Arch) String() string {
@@ -234,12 +235,14 @@ var (
ArchType: Arm,
ArchVariant: "armv7-a-neon",
CpuVariant: "cortex-a15",
+ Abi: "armeabi-v7a",
}
arm64Arch = Arch{
HostOrDevice: Device,
ArchType: Arm64,
ArchVariant: "armv8-a",
CpuVariant: "denver",
+ Abi: "arm64-v8a",
}
hostArch = Arch{
HostOrDevice: Host,
diff --git a/root.bp b/root.bp
index 247c96c7..760e5dc1 100644
--- a/root.bp
+++ b/root.bp
@@ -5,5 +5,6 @@ subdirs = [
"bionic/*",
"external/*",
"libnativehelper",
+ "prebuilts/ndk",
"system/core/*",
]