1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930 |
- // 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
- // This file contains the module types for compiling C/C++ for Android, and converts the properties
- // into the flags and filenames necessary to pass to the compiler. The final creation of the rules
- // is handled in builder.go
- import (
- "fmt"
- "path/filepath"
- "runtime"
- "strings"
- "github.com/google/blueprint"
- "github.com/google/blueprint/pathtools"
- "android/soong"
- "android/soong/common"
- "android/soong/genrule"
- )
- func init() {
- soong.RegisterModuleType("cc_library_static", CCLibraryStaticFactory)
- soong.RegisterModuleType("cc_library_shared", CCLibrarySharedFactory)
- soong.RegisterModuleType("cc_library", CCLibraryFactory)
- soong.RegisterModuleType("cc_object", CCObjectFactory)
- soong.RegisterModuleType("cc_binary", CCBinaryFactory)
- soong.RegisterModuleType("cc_test", CCTestFactory)
- soong.RegisterModuleType("cc_benchmark", CCBenchmarkFactory)
- soong.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
- soong.RegisterModuleType("ndk_prebuilt_library", NdkPrebuiltLibraryFactory)
- soong.RegisterModuleType("ndk_prebuilt_object", NdkPrebuiltObjectFactory)
- soong.RegisterModuleType("ndk_prebuilt_static_stl", NdkPrebuiltStaticStlFactory)
- soong.RegisterModuleType("ndk_prebuilt_shared_stl", NdkPrebuiltSharedStlFactory)
- soong.RegisterModuleType("cc_library_host_static", CCLibraryHostStaticFactory)
- soong.RegisterModuleType("cc_library_host_shared", CCLibraryHostSharedFactory)
- soong.RegisterModuleType("cc_binary_host", CCBinaryHostFactory)
- soong.RegisterModuleType("cc_test_host", CCTestHostFactory)
- soong.RegisterModuleType("cc_benchmark_host", CCBenchmarkHostFactory)
- // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
- // the Go initialization order because this package depends on common, so common's init
- // functions will run first.
- soong.RegisterEarlyMutator("link", LinkageMutator)
- soong.RegisterEarlyMutator("test_per_src", TestPerSrcMutator)
- }
- var (
- HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS)
- SrcDir = pctx.VariableConfigMethod("SrcDir", common.Config.SrcDir)
- LibcRoot = pctx.StaticVariable("LibcRoot", "bionic/libc")
- LibmRoot = pctx.StaticVariable("LibmRoot", "bionic/libm")
- )
- // Flags used by lots of devices. Putting them in package static variables will save bytes in
- // build.ninja so they aren't repeated for every file
- var (
- commonGlobalCflags = []string{
- "-DANDROID",
- "-fmessage-length=0",
- "-W",
- "-Wall",
- "-Wno-unused",
- "-Winit-self",
- "-Wpointer-arith",
- // COMMON_RELEASE_CFLAGS
- "-DNDEBUG",
- "-UDEBUG",
- }
- deviceGlobalCflags = []string{
- // TARGET_ERROR_FLAGS
- "-Werror=return-type",
- "-Werror=non-virtual-dtor",
- "-Werror=address",
- "-Werror=sequence-point",
- }
- hostGlobalCflags = []string{}
- commonGlobalCppflags = []string{
- "-Wsign-promo",
- }
- illegalFlags = []string{
- "-w",
- }
- )
- func init() {
- pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " "))
- pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " "))
- pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " "))
- pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
- pctx.StaticVariable("commonClangGlobalCflags",
- strings.Join(clangFilterUnknownCflags(commonGlobalCflags), " "))
- pctx.StaticVariable("deviceClangGlobalCflags",
- strings.Join(clangFilterUnknownCflags(deviceGlobalCflags), " "))
- pctx.StaticVariable("hostClangGlobalCflags",
- strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " "))
- pctx.StaticVariable("commonClangGlobalCppflags",
- strings.Join(clangFilterUnknownCflags(commonGlobalCppflags), " "))
- // Everything in this list is a crime against abstraction and dependency tracking.
- // Do not add anything to this list.
- pctx.StaticVariable("commonGlobalIncludes", strings.Join([]string{
- "-isystem ${SrcDir}/system/core/include",
- "-isystem ${SrcDir}/hardware/libhardware/include",
- "-isystem ${SrcDir}/hardware/libhardware_legacy/include",
- "-isystem ${SrcDir}/hardware/ril/include",
- "-isystem ${SrcDir}/libnativehelper/include",
- "-isystem ${SrcDir}/frameworks/native/include",
- "-isystem ${SrcDir}/frameworks/native/opengl/include",
- "-isystem ${SrcDir}/frameworks/av/include",
- "-isystem ${SrcDir}/frameworks/base/include",
- }, " "))
- pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/")
- }
- // Building C/C++ code is handled by objects that satisfy this interface via composition
- type CCModuleType interface {
- common.AndroidModule
- // Modify property values after parsing Blueprints file but before starting dependency
- // resolution or build rule generation
- ModifyProperties(common.AndroidBaseContext)
- // Modify the ccFlags
- flags(common.AndroidModuleContext, CCFlags) CCFlags
- // Return list of dependency names for use in AndroidDynamicDependencies and in depsToPaths
- depNames(common.AndroidBaseContext, CCDeps) CCDeps
- // Compile objects into final module
- compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string)
- // Install the built module.
- installModule(common.AndroidModuleContext, CCFlags)
- // Return the output file (.o, .a or .so) for use by other modules
- outputFile() string
- }
- type CCDeps struct {
- StaticLibs, SharedLibs, LateStaticLibs, WholeStaticLibs, ObjFiles, Cflags []string
- WholeStaticLibObjFiles []string
- CrtBegin, CrtEnd string
- }
- type CCFlags struct {
- GlobalFlags []string // Flags that apply to C, C++, and assembly source files
- AsFlags []string // Flags that apply to assembly source files
- CFlags []string // Flags that apply to C and C++ source files
- ConlyFlags []string // Flags that apply to C source files
- CppFlags []string // Flags that apply to C++ source files
- YaccFlags []string // Flags that apply to Yacc source files
- LdFlags []string // Flags that apply to linker command lines
- Nocrt bool
- Toolchain Toolchain
- Clang bool
- }
- // Properties used to compile all C or C++ modules
- type CCBaseProperties struct {
- // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
- Srcs []string `android:"arch_variant"`
- // list of source files that should not be used to build the C/C++ module.
- // This is most useful in the arch/multilib variants to remove non-common files
- Exclude_srcs []string `android:"arch_variant"`
- // list of module-specific flags that will be used for C and C++ compiles.
- Cflags []string `android:"arch_variant"`
- // list of module-specific flags that will be used for C++ compiles
- Cppflags []string `android:"arch_variant"`
- // list of module-specific flags that will be used for C compiles
- Conlyflags []string `android:"arch_variant"`
- // list of module-specific flags that will be used for .S compiles
- Asflags []string `android:"arch_variant"`
- // list of module-specific flags that will be used for .y and .yy compiles
- Yaccflags []string
- // list of module-specific flags that will be used for all link steps
- Ldflags []string `android:"arch_variant"`
- // the instruction set architecture to use to compile the C/C++
- // module.
- Instruction_set string `android:"arch_variant"`
- // list of directories relative to the root of the source tree that will
- // be added to the include path using -I.
- // If possible, don't use this. If adding paths from the current directory use
- // local_include_dirs, if adding paths from other modules use export_include_dirs in
- // that module.
- Include_dirs []string `android:"arch_variant"`
- // list of files relative to the root of the source tree that will be included
- // using -include.
- // If possible, don't use this.
- Include_files []string `android:"arch_variant"`
- // list of directories relative to the Blueprints file that will
- // be added to the include path using -I
- Local_include_dirs []string `android:"arch_variant"`
- // list of files relative to the Blueprints file that will be included
- // using -include.
- // If possible, don't use this.
- Local_include_files []string `android:"arch_variant"`
- // 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 `android:"arch_variant"`
- // list of module-specific flags that will be used for C and C++ compiles when
- // compiling with clang
- Clang_cflags []string `android:"arch_variant"`
- // list of module-specific flags that will be used for .S compiles when
- // compiling with clang
- Clang_asflags []string `android:"arch_variant"`
- // list of system libraries that will be dynamically linked to
- // shared library and executable modules. If unset, generally defaults to libc
- // and libm. Set to [] to prevent linking against libc and libm.
- System_shared_libs []string
- // list of modules whose object files should be linked into this module
- // in their entirety. For static library modules, all of the .o files from the intermediate
- // directory of the dependency will be linked into this modules .a file. For a shared library,
- // the dependency's .a file will be linked into this module using -Wl,--whole-archive.
- Whole_static_libs []string `android:"arch_variant"`
- // list of modules that should be statically linked into this module.
- Static_libs []string `android:"arch_variant"`
- // list of modules that should be dynamically linked into this module.
- Shared_libs []string `android:"arch_variant"`
- // allow the module to contain undefined symbols. By default,
- // modules cannot contain undefined symbols that are not satisified by their immediate
- // dependencies. Set this flag to true to remove --no-undefined from the linker flags.
- // This flag should only be necessary for compiling low-level libraries like libc.
- Allow_undefined_symbols bool
- // don't link in crt_begin and crt_end. This flag should only be necessary for
- // compiling crt or libc.
- Nocrt bool `android:"arch_variant"`
- // don't link in libgcc.a
- No_libgcc bool
- // don't insert default compiler flags into asflags, cflags,
- // cppflags, conlyflags, ldflags, or include_dirs
- No_default_compiler_flags bool
- // compile module with clang instead of gcc
- Clang bool `android:"arch_variant"`
- // pass -frtti instead of -fno-rtti
- Rtti bool
- // -l arguments to pass to linker for host-provided shared libraries
- Host_ldlibs []string `android:"arch_variant"`
- // select the STL library to use. Possible values are "libc++", "libc++_static",
- // "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
- // default
- Stl string
- // Set for combined shared/static libraries to prevent compiling object files a second time
- SkipCompileObjs bool `blueprint:"mutated"`
- Debug, Release struct {
- // list of module-specific flags that will be used for C and C++ compiles in debug or
- // release builds
- Cflags []string `android:"arch_variant"`
- } `android:"arch_variant"`
- // Minimum sdk version supported when compiling against the ndk
- Sdk_version string
- // install to a subdirectory of the default install path for the module
- Relative_install_path string
- }
- // CCBase contains the properties and members used by all C/C++ module types, and implements
- // the blueprint.Module interface. It expects to be embedded into an outer specialization struct,
- // and uses a ccModuleType interface to that struct to create the build steps.
- type CCBase struct {
- common.AndroidModuleBase
- module CCModuleType
- Properties CCBaseProperties
- unused struct {
- Native_coverage bool
- Required []string
- Sanitize []string `android:"arch_variant"`
- Sanitize_recover []string
- Strip string
- Tags []string
- }
- installPath string
- savedDepNames CCDeps
- }
- func newCCBase(base *CCBase, module CCModuleType, hod common.HostOrDeviceSupported,
- multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
- base.module = module
- props = append(props, &base.Properties, &base.unused)
- return common.InitAndroidArchModule(module, hod, multilib, props...)
- }
- func (c *CCBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
- toolchain := c.findToolchain(ctx)
- if ctx.Failed() {
- return
- }
- flags := c.collectFlags(ctx, toolchain)
- if ctx.Failed() {
- return
- }
- deps := c.depsToPaths(ctx, c.savedDepNames)
- if ctx.Failed() {
- return
- }
- flags.CFlags = append(flags.CFlags, deps.Cflags...)
- objFiles := c.compileObjs(ctx, flags)
- if ctx.Failed() {
- return
- }
- generatedObjFiles := c.compileGeneratedObjs(ctx, flags)
- if ctx.Failed() {
- return
- }
- objFiles = append(objFiles, generatedObjFiles...)
- c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
- if ctx.Failed() {
- return
- }
- c.ccModuleType().installModule(ctx, flags)
- if ctx.Failed() {
- return
- }
- }
- func (c *CCBase) ccModuleType() CCModuleType {
- return c.module
- }
- var _ common.AndroidDynamicDepender = (*CCBase)(nil)
- func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
- arch := ctx.Arch()
- hod := ctx.HostOrDevice()
- factory := toolchainFactories[hod][arch.ArchType]
- if factory == nil {
- panic(fmt.Sprintf("Toolchain not found for %s arch %q",
- hod.String(), arch.String()))
- }
- return factory(arch.ArchVariant, arch.CpuVariant)
- }
- func (c *CCBase) ModifyProperties(ctx common.AndroidBaseContext) {
- }
- 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...)
- depNames.SharedLibs = append(depNames.SharedLibs, c.Properties.Shared_libs...)
- return depNames
- }
- func (c *CCBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
- c.module.ModifyProperties(ctx)
- c.savedDepNames = c.module.depNames(ctx, CCDeps{})
- c.savedDepNames.WholeStaticLibs = lastUniqueElements(c.savedDepNames.WholeStaticLibs)
- c.savedDepNames.StaticLibs = lastUniqueElements(c.savedDepNames.StaticLibs)
- c.savedDepNames.SharedLibs = lastUniqueElements(c.savedDepNames.SharedLibs)
- staticLibs := c.savedDepNames.WholeStaticLibs
- staticLibs = append(staticLibs, c.savedDepNames.StaticLibs...)
- staticLibs = append(staticLibs, c.savedDepNames.LateStaticLibs...)
- ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...)
- ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.savedDepNames.SharedLibs...)
- ret := append([]string(nil), c.savedDepNames.ObjFiles...)
- if c.savedDepNames.CrtBegin != "" {
- ret = append(ret, c.savedDepNames.CrtBegin)
- }
- if c.savedDepNames.CrtEnd != "" {
- ret = append(ret, c.savedDepNames.CrtEnd)
- }
- return ret
- }
- // Create a ccFlags struct that collects the compile flags from global values,
- // per-target values, module type values, and per-module Blueprints properties
- func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolchain) CCFlags {
- flags := CCFlags{
- CFlags: c.Properties.Cflags,
- CppFlags: c.Properties.Cppflags,
- ConlyFlags: c.Properties.Conlyflags,
- LdFlags: c.Properties.Ldflags,
- AsFlags: c.Properties.Asflags,
- YaccFlags: c.Properties.Yaccflags,
- Nocrt: c.Properties.Nocrt,
- Toolchain: toolchain,
- Clang: c.Properties.Clang,
- }
- // Include dir cflags
- common.CheckSrcDirsExist(ctx, c.Properties.Include_dirs, "include_dirs")
- common.CheckModuleSrcDirsExist(ctx, c.Properties.Local_include_dirs, "local_include_dirs")
- rootIncludeDirs := pathtools.PrefixPaths(c.Properties.Include_dirs, ctx.AConfig().SrcDir())
- localIncludeDirs := pathtools.PrefixPaths(c.Properties.Local_include_dirs, common.ModuleSrcDir(ctx))
- flags.GlobalFlags = append(flags.GlobalFlags,
- includeDirsToFlags(rootIncludeDirs),
- includeDirsToFlags(localIncludeDirs))
- rootIncludeFiles := pathtools.PrefixPaths(c.Properties.Include_files, ctx.AConfig().SrcDir())
- localIncludeFiles := pathtools.PrefixPaths(c.Properties.Local_include_files, common.ModuleSrcDir(ctx))
- flags.GlobalFlags = append(flags.GlobalFlags,
- includeFilesToFlags(rootIncludeFiles),
- includeFilesToFlags(localIncludeFiles))
- if !c.Properties.No_default_compiler_flags {
- if c.Properties.Sdk_version == "" || ctx.Host() {
- flags.GlobalFlags = append(flags.GlobalFlags,
- "${commonGlobalIncludes}",
- toolchain.IncludeFlags(),
- "-I${SrcDir}/libnativehelper/include/nativehelper")
- }
- flags.GlobalFlags = append(flags.GlobalFlags, []string{
- "-I" + common.ModuleSrcDir(ctx),
- "-I" + common.ModuleOutDir(ctx),
- "-I" + common.ModuleGenDir(ctx),
- }...)
- }
- instructionSet := c.Properties.Instruction_set
- instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
- if err != nil {
- ctx.ModuleErrorf("%s", err)
- }
- // TODO: debug
- flags.CFlags = append(flags.CFlags, c.Properties.Release.Cflags...)
- if ctx.Host() && !ctx.ContainsProperty("clang") {
- flags.Clang = true
- }
- if flags.Clang {
- flags.CFlags = clangFilterUnknownCflags(flags.CFlags)
- flags.CFlags = append(flags.CFlags, c.Properties.Clang_cflags...)
- flags.AsFlags = append(flags.AsFlags, c.Properties.Clang_asflags...)
- flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags)
- flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags)
- flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags)
- flags.CFlags = append(flags.CFlags, "${clangExtraCflags}")
- flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}")
- if ctx.Device() {
- flags.CFlags = append(flags.CFlags, "${clangExtraTargetCflags}")
- }
- target := "-target " + toolchain.ClangTriple()
- gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin")
- flags.CFlags = append(flags.CFlags, target, gccPrefix)
- flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
- flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
- }
- if !c.Properties.No_default_compiler_flags {
- if ctx.Device() && !c.Properties.Allow_undefined_symbols {
- flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
- }
- flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
- if flags.Clang {
- flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}")
- flags.GlobalFlags = append(flags.GlobalFlags,
- toolchain.ClangCflags(),
- "${commonClangGlobalCflags}",
- fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice()))
- } else {
- flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}")
- flags.GlobalFlags = append(flags.GlobalFlags,
- toolchain.Cflags(),
- "${commonGlobalCflags}",
- fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice()))
- }
- if ctx.Device() {
- if c.Properties.Rtti {
- flags.CppFlags = append(flags.CppFlags, "-frtti")
- } else {
- flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
- }
- }
- flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
- if flags.Clang {
- flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags())
- flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags())
- } else {
- flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags())
- flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags())
- }
- if ctx.Host() {
- flags.LdFlags = append(flags.LdFlags, c.Properties.Host_ldlibs...)
- }
- }
- flags = c.ccModuleType().flags(ctx, flags)
- if c.Properties.Sdk_version == "" {
- if ctx.Host() && !flags.Clang {
- // The host GCC doesn't support C++14 (and is deprecated, so likely
- // never will). Build these modules with C++11.
- flags.CppFlags = append(flags.CppFlags, "-std=gnu++11")
- } else {
- flags.CppFlags = append(flags.CppFlags, "-std=gnu++14")
- }
- }
- flags.CFlags, _ = filterList(flags.CFlags, illegalFlags)
- flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags)
- flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags)
- // Optimization to reduce size of build.ninja
- // Replace the long list of flags for each file with a module-local variable
- ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " "))
- ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " "))
- ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " "))
- flags.CFlags = []string{"$cflags"}
- flags.CppFlags = []string{"$cppflags"}
- flags.AsFlags = []string{"$asflags"}
- return flags
- }
- func (c *CCBase) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
- return flags
- }
- // Compile a list of source files into objects a specified subdirectory
- func (c *CCBase) customCompileObjs(ctx common.AndroidModuleContext, flags CCFlags,
- subdir string, srcFiles, excludes []string) []string {
- buildFlags := ccFlagsToBuilderFlags(flags)
- srcFiles = ctx.ExpandSources(srcFiles, excludes)
- srcFiles, deps := genSources(ctx, srcFiles, buildFlags)
- return TransformSourceToObj(ctx, subdir, srcFiles, buildFlags, deps)
- }
- // Compile files listed in c.Properties.Srcs into objects
- func (c *CCBase) compileObjs(ctx common.AndroidModuleContext, flags CCFlags) []string {
- if c.Properties.SkipCompileObjs {
- return nil
- }
- return c.customCompileObjs(ctx, flags, "", c.Properties.Srcs, c.Properties.Exclude_srcs)
- }
- // Compile generated source files from dependencies
- func (c *CCBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags CCFlags) []string {
- var srcs []string
- if c.Properties.SkipCompileObjs {
- return nil
- }
- ctx.VisitDirectDeps(func(module blueprint.Module) {
- if gen, ok := module.(genrule.SourceFileGenerator); ok {
- srcs = append(srcs, gen.GeneratedSourceFiles()...)
- }
- })
- if len(srcs) == 0 {
- return nil
- }
- return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags), nil)
- }
- func (c *CCBase) outputFile() string {
- return ""
- }
- func (c *CCBase) depsToPathsFromList(ctx common.AndroidModuleContext,
- names []string) (modules []common.AndroidModule,
- outputFiles []string, exportedFlags []string) {
- for _, n := range names {
- found := false
- ctx.VisitDirectDeps(func(m blueprint.Module) {
- otherName := ctx.OtherModuleName(m)
- if otherName != n {
- return
- }
- if a, ok := m.(CCModuleType); ok {
- if a.Disabled() {
- // If a cc_library host+device module depends on a library that exists as both
- // cc_library_shared and cc_library_host_shared, it will end up with two
- // dependencies with the same name, one of which is marked disabled for each
- // of host and device. Ignore the disabled one.
- return
- }
- if a.HostOrDevice() != ctx.HostOrDevice() {
- ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(),
- otherName)
- return
- }
- if outputFile := a.outputFile(); outputFile != "" {
- if found {
- ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName)
- return
- }
- outputFiles = append(outputFiles, outputFile)
- modules = append(modules, a)
- if i, ok := a.(ccExportedFlagsProducer); ok {
- exportedFlags = append(exportedFlags, i.exportedFlags()...)
- }
- found = true
- } else {
- ctx.ModuleErrorf("module %q missing output file", otherName)
- return
- }
- } else {
- ctx.ModuleErrorf("module %q not an android module", otherName)
- return
- }
- })
- if !found {
- ctx.ModuleErrorf("unsatisified dependency on %q", n)
- }
- }
- return modules, outputFiles, exportedFlags
- }
- // Convert depenedency names to paths. Takes a CCDeps containing names and returns a CCDeps
- // containing paths
- func (c *CCBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) CCDeps {
- var depPaths CCDeps
- var newCflags []string
- var wholeStaticLibModules []common.AndroidModule
- wholeStaticLibModules, depPaths.WholeStaticLibs, newCflags =
- c.depsToPathsFromList(ctx, depNames.WholeStaticLibs)
- depPaths.Cflags = append(depPaths.Cflags, newCflags...)
- for _, m := range wholeStaticLibModules {
- if staticLib, ok := m.(ccLibraryInterface); ok && staticLib.static() {
- depPaths.WholeStaticLibObjFiles =
- append(depPaths.WholeStaticLibObjFiles, staticLib.allObjFiles()...)
- } else {
- ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m))
- }
- }
- _, depPaths.StaticLibs, newCflags = c.depsToPathsFromList(ctx, depNames.StaticLibs)
- depPaths.Cflags = append(depPaths.Cflags, newCflags...)
- _, depPaths.LateStaticLibs, newCflags = c.depsToPathsFromList(ctx, depNames.LateStaticLibs)
- depPaths.Cflags = append(depPaths.Cflags, newCflags...)
- _, depPaths.SharedLibs, newCflags = c.depsToPathsFromList(ctx, depNames.SharedLibs)
- depPaths.Cflags = append(depPaths.Cflags, newCflags...)
- ctx.VisitDirectDeps(func(m blueprint.Module) {
- if obj, ok := m.(ccObjectProvider); ok {
- otherName := ctx.OtherModuleName(m)
- if otherName == depNames.CrtBegin {
- if !c.Properties.Nocrt {
- depPaths.CrtBegin = obj.object().outputFile()
- }
- } else if otherName == depNames.CrtEnd {
- if !c.Properties.Nocrt {
- depPaths.CrtEnd = obj.object().outputFile()
- }
- } else {
- depPaths.ObjFiles = append(depPaths.ObjFiles, obj.object().outputFile())
- }
- }
- })
- return depPaths
- }
- type ccLinkedProperties struct {
- VariantIsShared bool `blueprint:"mutated"`
- VariantIsStatic bool `blueprint:"mutated"`
- VariantIsStaticBinary bool `blueprint:"mutated"`
- }
- // CCLinked contains the properties and members used by libraries and executables
- type CCLinked struct {
- CCBase
- dynamicProperties ccLinkedProperties
- }
- func newCCDynamic(dynamic *CCLinked, module CCModuleType, hod common.HostOrDeviceSupported,
- multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
- props = append(props, &dynamic.dynamicProperties)
- return newCCBase(&dynamic.CCBase, module, hod, multilib, props...)
- }
- func (c *CCLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
- if ctx.ContainsProperty("system_shared_libs") {
- return c.Properties.System_shared_libs
- } else if ctx.Device() && c.Properties.Sdk_version == "" {
- return []string{"libc", "libm"}
- } else {
- return nil
- }
- }
- func (c *CCLinked) stl(ctx common.AndroidBaseContext) string {
- if c.Properties.Sdk_version != "" && ctx.Device() {
- switch c.Properties.Stl {
- case "":
- return "ndk_system"
- case "c++_shared", "c++_static",
- "stlport_shared", "stlport_static",
- "gnustl_static":
- return "ndk_lib" + c.Properties.Stl
- default:
- ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", c.Properties.Stl)
- return ""
- }
- }
- 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++
- }
- default:
- ctx.ModuleErrorf("stl: %q is not a supported STL", c.Properties.Stl)
- return ""
- }
- }
- var hostDynamicGccLibs, hostStaticGccLibs []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"}
- }
- }
- func (c *CCLinked) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
- stl := c.stl(ctx)
- if ctx.Failed() {
- return flags
- }
- switch stl {
- case "libc++", "libc++_static":
- flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
- flags.CFlags = append(flags.CFlags, "-I${SrcDir}/external/libcxx/include")
- if ctx.Host() {
- flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
- flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
- flags.LdFlags = append(flags.LdFlags, "-lm", "-lpthread")
- if c.staticBinary() {
- flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
- } else {
- flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
- }
- } else {
- if ctx.Arch().ArchType == common.Arm {
- flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,libunwind_llvm.a")
- }
- }
- 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.
- // Host builds will use GNU libstdc++.
- if ctx.Device() {
- flags.CFlags = append(flags.CFlags, "-I${SrcDir}/bionic/libstdc++/include")
- }
- case "ndk_system":
- ndkSrcRoot := ctx.AConfig().SrcDir() + "/prebuilts/ndk/current/sources/"
- flags.CFlags = append(flags.CFlags, "-isystem "+ndkSrcRoot+"cxx-stl/system/include")
- case "ndk_libc++_shared", "ndk_libc++_static":
- // TODO(danalbert): This really shouldn't be here...
- flags.CppFlags = append(flags.CppFlags, "-std=c++11")
- case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
- // Nothing
- case "":
- // None or error.
- if ctx.Host() {
- flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
- flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
- if c.staticBinary() {
- flags.LdFlags = append(flags.LdFlags, hostStaticGccLibs...)
- } else {
- flags.LdFlags = append(flags.LdFlags, hostDynamicGccLibs...)
- }
- }
- default:
- panic(fmt.Errorf("Unknown stl in CCLinked.Flags: %q", stl))
- }
- return flags
- }
- func (c *CCLinked) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- depNames = c.CCBase.depNames(ctx, depNames)
- stl := c.stl(ctx)
- if ctx.Failed() {
- return depNames
- }
- switch stl {
- case "libstdc++":
- if ctx.Device() {
- depNames.SharedLibs = append(depNames.SharedLibs, stl)
- }
- case "libc++", "libc++_static":
- if stl == "libc++" {
- depNames.SharedLibs = append(depNames.SharedLibs, stl)
- } else {
- depNames.StaticLibs = append(depNames.StaticLibs, stl)
- }
- if ctx.Device() {
- if ctx.Arch().ArchType == common.Arm {
- depNames.StaticLibs = append(depNames.StaticLibs, "libunwind_llvm")
- }
- if c.staticBinary() {
- depNames.StaticLibs = append(depNames.StaticLibs, "libdl")
- } else {
- depNames.SharedLibs = append(depNames.SharedLibs, "libdl")
- }
- }
- case "":
- // None or error.
- case "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().
- depNames.SharedLibs = append([]string{"libstdc++"}, depNames.SharedLibs...)
- case "ndk_libc++_shared", "ndk_libstlport_shared":
- depNames.SharedLibs = append(depNames.SharedLibs, stl)
- case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
- depNames.StaticLibs = append(depNames.StaticLibs, stl)
- default:
- panic(fmt.Errorf("Unknown stl in CCLinked.depNames: %q", stl))
- }
- if ctx.ModuleName() != "libcompiler_rt-extras" {
- depNames.StaticLibs = append(depNames.StaticLibs, "libcompiler_rt-extras")
- }
- if ctx.Device() {
- // libgcc and libatomic have to be last on the command line
- depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic")
- if !c.Properties.No_libgcc {
- depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcc")
- }
- if !c.static() {
- depNames.SharedLibs = append(depNames.SharedLibs, c.systemSharedLibs(ctx)...)
- }
- if c.Properties.Sdk_version != "" {
- version := c.Properties.Sdk_version
- depNames.SharedLibs = append(depNames.SharedLibs,
- "ndk_libc."+version,
- "ndk_libm."+version,
- )
- }
- }
- return depNames
- }
- // ccLinkedInterface interface is used on ccLinked to deal with static or shared variants
- type ccLinkedInterface interface {
- // Returns true if the build options for the module have selected a static or shared build
- buildStatic() bool
- buildShared() bool
- // Sets whether a specific variant is static or shared
- setStatic(bool)
- // Returns whether a specific variant is a static library or binary
- static() bool
- // Returns whether a module is a static binary
- staticBinary() bool
- }
- var _ ccLinkedInterface = (*CCLibrary)(nil)
- var _ ccLinkedInterface = (*CCBinary)(nil)
- func (c *CCLinked) static() bool {
- return c.dynamicProperties.VariantIsStatic
- }
- func (c *CCLinked) staticBinary() bool {
- return c.dynamicProperties.VariantIsStaticBinary
- }
- func (c *CCLinked) setStatic(static bool) {
- c.dynamicProperties.VariantIsStatic = static
- }
- type ccExportedFlagsProducer interface {
- exportedFlags() []string
- }
- //
- // Combined static+shared libraries
- //
- type CCLibraryProperties struct {
- BuildStatic bool `blueprint:"mutated"`
- BuildShared bool `blueprint:"mutated"`
- Static struct {
- Srcs []string `android:"arch_variant"`
- Exclude_srcs []string `android:"arch_variant"`
- Cflags []string `android:"arch_variant"`
- Whole_static_libs []string `android:"arch_variant"`
- Static_libs []string `android:"arch_variant"`
- Shared_libs []string `android:"arch_variant"`
- } `android:"arch_variant"`
- Shared struct {
- Srcs []string `android:"arch_variant"`
- Exclude_srcs []string `android:"arch_variant"`
- Cflags []string `android:"arch_variant"`
- Whole_static_libs []string `android:"arch_variant"`
- Static_libs []string `android:"arch_variant"`
- Shared_libs []string `android:"arch_variant"`
- } `android:"arch_variant"`
- // local file name to pass to the linker as --version_script
- Version_script string `android:"arch_variant"`
- }
- type CCLibrary struct {
- CCLinked
- reuseFrom ccLibraryInterface
- reuseObjFiles []string
- objFiles []string
- exportFlags []string
- out string
- LibraryProperties CCLibraryProperties
- }
- func (c *CCLibrary) buildStatic() bool {
- return c.LibraryProperties.BuildStatic
- }
- func (c *CCLibrary) buildShared() bool {
- return c.LibraryProperties.BuildShared
- }
- type ccLibraryInterface interface {
- ccLinkedInterface
- ccLibrary() *CCLibrary
- setReuseFrom(ccLibraryInterface)
- getReuseFrom() ccLibraryInterface
- getReuseObjFiles() []string
- allObjFiles() []string
- }
- var _ ccLibraryInterface = (*CCLibrary)(nil)
- func (c *CCLibrary) ccLibrary() *CCLibrary {
- return c
- }
- func NewCCLibrary(library *CCLibrary, module CCModuleType,
- hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
- return newCCDynamic(&library.CCLinked, module, hod, common.MultilibBoth,
- &library.LibraryProperties)
- }
- func CCLibraryFactory() (blueprint.Module, []interface{}) {
- module := &CCLibrary{}
- module.LibraryProperties.BuildShared = true
- module.LibraryProperties.BuildStatic = true
- return NewCCLibrary(module, module, common.HostAndDeviceSupported)
- }
- func (c *CCLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- depNames = c.CCLinked.depNames(ctx, depNames)
- if c.static() {
- depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.LibraryProperties.Static.Whole_static_libs...)
- depNames.StaticLibs = append(depNames.StaticLibs, c.LibraryProperties.Static.Static_libs...)
- depNames.SharedLibs = append(depNames.SharedLibs, c.LibraryProperties.Static.Shared_libs...)
- } else {
- if ctx.Device() {
- if c.Properties.Sdk_version == "" {
- depNames.CrtBegin = "crtbegin_so"
- depNames.CrtEnd = "crtend_so"
- } else {
- depNames.CrtBegin = "ndk_crtbegin_so." + c.Properties.Sdk_version
- depNames.CrtEnd = "ndk_crtend_so." + c.Properties.Sdk_version
- }
- }
- depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.LibraryProperties.Shared.Whole_static_libs...)
- depNames.StaticLibs = append(depNames.StaticLibs, c.LibraryProperties.Shared.Static_libs...)
- depNames.SharedLibs = append(depNames.SharedLibs, c.LibraryProperties.Shared.Shared_libs...)
- }
- return depNames
- }
- func (c *CCLibrary) outputFile() string {
- return c.out
- }
- func (c *CCLibrary) getReuseObjFiles() []string {
- return c.reuseObjFiles
- }
- func (c *CCLibrary) setReuseFrom(reuseFrom ccLibraryInterface) {
- c.reuseFrom = reuseFrom
- }
- func (c *CCLibrary) getReuseFrom() ccLibraryInterface {
- return c.reuseFrom
- }
- func (c *CCLibrary) allObjFiles() []string {
- return c.objFiles
- }
- func (c *CCLibrary) exportedFlags() []string {
- return c.exportFlags
- }
- func (c *CCLibrary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
- flags = c.CCLinked.flags(ctx, flags)
- flags.CFlags = append(flags.CFlags, "-fPIC")
- if c.static() {
- flags.CFlags = append(flags.CFlags, c.LibraryProperties.Static.Cflags...)
- } else {
- flags.CFlags = append(flags.CFlags, c.LibraryProperties.Shared.Cflags...)
- }
- if !c.static() {
- libName := ctx.ModuleName()
- // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
- sharedFlag := "-Wl,-shared"
- if c.Properties.Clang || ctx.Host() {
- sharedFlag = "-shared"
- }
- if ctx.Device() {
- flags.LdFlags = append(flags.LdFlags, "-nostdlib")
- }
- if ctx.Darwin() {
- flags.LdFlags = append(flags.LdFlags,
- "-dynamiclib",
- "-single_module",
- //"-read_only_relocs suppress",
- "-install_name @rpath/"+libName+sharedLibraryExtension,
- )
- } else {
- flags.LdFlags = append(flags.LdFlags,
- "-Wl,--gc-sections",
- sharedFlag,
- "-Wl,-soname,"+libName+sharedLibraryExtension,
- )
- }
- }
- return flags
- }
- func (c *CCLibrary) compileStaticLibrary(ctx common.AndroidModuleContext,
- flags CCFlags, deps CCDeps, objFiles []string) {
- staticFlags := flags
- objFilesStatic := c.customCompileObjs(ctx, staticFlags, common.DeviceStaticLibrary,
- c.LibraryProperties.Static.Srcs, c.LibraryProperties.Static.Exclude_srcs)
- objFiles = append(objFiles, objFilesStatic...)
- objFiles = append(objFiles, deps.WholeStaticLibObjFiles...)
- outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+staticLibraryExtension)
- if ctx.Darwin() {
- TransformDarwinObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
- } else {
- TransformObjToStaticLib(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
- }
- c.objFiles = objFiles
- c.out = outputFile
- common.CheckModuleSrcDirsExist(ctx, c.Properties.Export_include_dirs, "export_include_dirs")
- includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
- c.exportFlags = []string{includeDirsToFlags(includeDirs)}
- ctx.CheckbuildFile(outputFile)
- }
- func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
- flags CCFlags, deps CCDeps, objFiles []string) {
- sharedFlags := flags
- objFilesShared := c.customCompileObjs(ctx, sharedFlags, common.DeviceSharedLibrary,
- c.LibraryProperties.Shared.Srcs, c.LibraryProperties.Shared.Exclude_srcs)
- objFiles = append(objFiles, objFilesShared...)
- outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
- var linkerDeps []string
- if c.LibraryProperties.Version_script != "" {
- versionScript := filepath.Join(common.ModuleSrcDir(ctx), c.LibraryProperties.Version_script)
- sharedFlags.LdFlags = append(sharedFlags.LdFlags, "-Wl,--version-script,"+versionScript)
- linkerDeps = append(linkerDeps, versionScript)
- }
- TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
- deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, false,
- ccFlagsToBuilderFlags(flags), outputFile)
- c.out = outputFile
- includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
- c.exportFlags = []string{includeDirsToFlags(includeDirs)}
- }
- func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
- flags CCFlags, deps CCDeps, objFiles []string) {
- // Reuse the object files from the matching static library if it exists
- if c.getReuseFrom().ccLibrary() == c {
- c.reuseObjFiles = objFiles
- } else {
- if c.getReuseFrom().ccLibrary().LibraryProperties.Static.Cflags == nil &&
- c.LibraryProperties.Shared.Cflags == nil {
- objFiles = append([]string(nil), c.getReuseFrom().getReuseObjFiles()...)
- }
- }
- if c.static() {
- c.compileStaticLibrary(ctx, flags, deps, objFiles)
- } else {
- c.compileSharedLibrary(ctx, flags, deps, objFiles)
- }
- }
- func (c *CCLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
- // Static libraries do not get installed.
- }
- func (c *CCLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags CCFlags) {
- installDir := "lib"
- if flags.Toolchain.Is64Bit() {
- installDir = "lib64"
- }
- ctx.InstallFile(filepath.Join(installDir, c.Properties.Relative_install_path), c.out)
- }
- func (c *CCLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- if c.static() {
- c.installStaticLibrary(ctx, flags)
- } else {
- c.installSharedLibrary(ctx, flags)
- }
- }
- //
- // Objects (for crt*.o)
- //
- type ccObjectProvider interface {
- object() *ccObject
- }
- type ccObject struct {
- CCBase
- out string
- }
- func (c *ccObject) object() *ccObject {
- return c
- }
- func CCObjectFactory() (blueprint.Module, []interface{}) {
- module := &ccObject{}
- return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth)
- }
- func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
- // object files can't have any dynamic dependencies
- return nil
- }
- func (*ccObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- // object files can't have any dynamic dependencies
- return CCDeps{}
- }
- func (c *ccObject) compileModule(ctx common.AndroidModuleContext,
- flags CCFlags, deps CCDeps, objFiles []string) {
- objFiles = append(objFiles, deps.ObjFiles...)
- var outputFile string
- if len(objFiles) == 1 {
- outputFile = objFiles[0]
- } else {
- outputFile = filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+objectExtension)
- TransformObjsToObj(ctx, objFiles, ccFlagsToBuilderFlags(flags), outputFile)
- }
- c.out = outputFile
- ctx.CheckbuildFile(outputFile)
- }
- func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- // Object files do not get installed.
- }
- func (c *ccObject) outputFile() string {
- return c.out
- }
- var _ ccObjectProvider = (*ccObject)(nil)
- //
- // Executables
- //
- type CCBinaryProperties struct {
- // compile executable with -static
- Static_executable bool
- // set the name of the output
- Stem string `android:"arch_variant"`
- // append to the name of the output
- Suffix string `android:"arch_variant"`
- // if set, add an extra objcopy --prefix-symbols= step
- Prefix_symbols string
- // Create a separate binary for each source file. Useful when there is
- // global state that can not be torn down and reset between each test suite.
- Test_per_src bool
- }
- type CCBinary struct {
- CCLinked
- out string
- installFile string
- BinaryProperties CCBinaryProperties
- }
- func (c *CCBinary) buildStatic() bool {
- return c.BinaryProperties.Static_executable
- }
- func (c *CCBinary) buildShared() bool {
- return !c.BinaryProperties.Static_executable
- }
- func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
- stem := ctx.ModuleName()
- if c.BinaryProperties.Stem != "" {
- stem = c.BinaryProperties.Stem
- }
- return stem + c.BinaryProperties.Suffix
- }
- func (c *CCBinary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- depNames = c.CCLinked.depNames(ctx, depNames)
- if ctx.Device() {
- if c.Properties.Sdk_version == "" {
- if c.BinaryProperties.Static_executable {
- depNames.CrtBegin = "crtbegin_static"
- } else {
- depNames.CrtBegin = "crtbegin_dynamic"
- }
- depNames.CrtEnd = "crtend_android"
- } else {
- if c.BinaryProperties.Static_executable {
- depNames.CrtBegin = "ndk_crtbegin_static." + c.Properties.Sdk_version
- } else {
- depNames.CrtBegin = "ndk_crtbegin_dynamic." + c.Properties.Sdk_version
- }
- depNames.CrtEnd = "ndk_crtend_android." + c.Properties.Sdk_version
- }
- if c.BinaryProperties.Static_executable {
- if c.stl(ctx) == "libc++_static" {
- depNames.StaticLibs = append(depNames.StaticLibs, "libm", "libc", "libdl")
- }
- // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
- // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
- // move them to the beginning of deps.LateStaticLibs
- var groupLibs []string
- depNames.StaticLibs, groupLibs = filterList(depNames.StaticLibs,
- []string{"libc", "libc_nomalloc", "libcompiler_rt"})
- depNames.LateStaticLibs = append(groupLibs, depNames.LateStaticLibs...)
- }
- }
- return depNames
- }
- func NewCCBinary(binary *CCBinary, module CCModuleType,
- hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
- props = append(props, &binary.BinaryProperties)
- return newCCDynamic(&binary.CCLinked, module, hod, common.MultilibFirst, props...)
- }
- func CCBinaryFactory() (blueprint.Module, []interface{}) {
- module := &CCBinary{}
- return NewCCBinary(module, module, common.HostAndDeviceSupported)
- }
- func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) {
- if ctx.Darwin() {
- c.BinaryProperties.Static_executable = false
- }
- if c.BinaryProperties.Static_executable {
- c.dynamicProperties.VariantIsStaticBinary = true
- }
- }
- func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
- flags = c.CCLinked.flags(ctx, flags)
- flags.CFlags = append(flags.CFlags, "-fpie")
- if ctx.Device() {
- if c.BinaryProperties.Static_executable {
- // Clang driver needs -static to create static executable.
- // However, bionic/linker uses -shared to overwrite.
- // Linker for x86 targets does not allow coexistance of -static and -shared,
- // so we add -static only if -shared is not used.
- if !inList("-shared", flags.LdFlags) {
- flags.LdFlags = append(flags.LdFlags, "-static")
- }
- flags.LdFlags = append(flags.LdFlags,
- "-nostdlib",
- "-Bstatic",
- "-Wl,--gc-sections",
- )
- } else {
- linker := "/system/bin/linker"
- if flags.Toolchain.Is64Bit() {
- linker = "/system/bin/linker64"
- }
- flags.LdFlags = append(flags.LdFlags,
- "-nostdlib",
- "-Bdynamic",
- fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
- "-Wl,--gc-sections",
- "-Wl,-z,nocopyreloc",
- )
- }
- } else if ctx.Darwin() {
- flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names")
- }
- return flags
- }
- func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
- flags CCFlags, deps CCDeps, objFiles []string) {
- if !c.BinaryProperties.Static_executable && inList("libc", c.Properties.Static_libs) {
- ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
- "from static libs or set static_executable: true")
- }
- outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
- c.out = outputFile
- if c.BinaryProperties.Prefix_symbols != "" {
- afterPrefixSymbols := outputFile
- outputFile = outputFile + ".intermediate"
- TransformBinaryPrefixSymbols(ctx, c.BinaryProperties.Prefix_symbols, outputFile,
- ccFlagsToBuilderFlags(flags), afterPrefixSymbols)
- }
- var linkerDeps []string
- TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
- deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
- ccFlagsToBuilderFlags(flags), outputFile)
- }
- func (c *CCBinary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- c.installFile = ctx.InstallFile(filepath.Join("bin", c.Properties.Relative_install_path), c.out)
- }
- func (c *CCBinary) HostToolPath() string {
- if c.HostOrDevice().Host() {
- return c.installFile
- }
- return ""
- }
- func (c *CCBinary) testPerSrc() bool {
- return c.BinaryProperties.Test_per_src
- }
- func (c *CCBinary) binary() *CCBinary {
- return c
- }
- type testPerSrc interface {
- binary() *CCBinary
- testPerSrc() bool
- }
- var _ testPerSrc = (*CCBinary)(nil)
- func TestPerSrcMutator(mctx blueprint.EarlyMutatorContext) {
- if test, ok := mctx.Module().(testPerSrc); ok {
- if test.testPerSrc() {
- testNames := make([]string, len(test.binary().Properties.Srcs))
- for i, src := range test.binary().Properties.Srcs {
- testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
- }
- tests := mctx.CreateLocalVariations(testNames...)
- for i, src := range test.binary().Properties.Srcs {
- tests[i].(testPerSrc).binary().Properties.Srcs = []string{src}
- tests[i].(testPerSrc).binary().BinaryProperties.Stem = mctx.ModuleName() + "_" + testNames[i]
- }
- }
- }
- }
- type CCTest struct {
- CCBinary
- }
- func (c *CCTest) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
- flags = c.CCBinary.flags(ctx, flags)
- flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING")
- if ctx.Host() {
- flags.CFlags = append(flags.CFlags, "-O0", "-g")
- flags.LdFlags = append(flags.LdFlags, "-lpthread")
- }
- // TODO(danalbert): Make gtest export its dependencies.
- flags.CFlags = append(flags.CFlags,
- "-I"+filepath.Join(ctx.AConfig().SrcDir(), "external/gtest/include"))
- return flags
- }
- func (c *CCTest) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- depNames.StaticLibs = append(depNames.StaticLibs, "libgtest", "libgtest_main")
- depNames = c.CCBinary.depNames(ctx, depNames)
- return depNames
- }
- func (c *CCTest) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- if ctx.Device() {
- ctx.InstallFile("../data/nativetest"+ctx.Arch().ArchType.Multilib[3:]+"/"+ctx.ModuleName(), c.out)
- } else {
- c.CCBinary.installModule(ctx, flags)
- }
- }
- func NewCCTest(test *CCTest, module CCModuleType,
- hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
- return NewCCBinary(&test.CCBinary, module, hod, props...)
- }
- func CCTestFactory() (blueprint.Module, []interface{}) {
- module := &CCTest{}
- return NewCCTest(module, module, common.HostAndDeviceSupported)
- }
- type CCBenchmark struct {
- CCBinary
- }
- func (c *CCBenchmark) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- depNames = c.CCBinary.depNames(ctx, depNames)
- depNames.StaticLibs = append(depNames.StaticLibs, "libbenchmark", "libbase")
- return depNames
- }
- func (c *CCBenchmark) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- if ctx.Device() {
- ctx.InstallFile("../data/nativetest"+ctx.Arch().ArchType.Multilib[3:]+"/"+ctx.ModuleName(), c.out)
- } else {
- c.CCBinary.installModule(ctx, flags)
- }
- }
- func NewCCBenchmark(test *CCBenchmark, module CCModuleType,
- hod common.HostOrDeviceSupported, props ...interface{}) (blueprint.Module, []interface{}) {
- return NewCCBinary(&test.CCBinary, module, hod, props...)
- }
- func CCBenchmarkFactory() (blueprint.Module, []interface{}) {
- module := &CCBenchmark{}
- return NewCCBenchmark(module, module, common.HostAndDeviceSupported)
- }
- //
- // Static library
- //
- func CCLibraryStaticFactory() (blueprint.Module, []interface{}) {
- module := &CCLibrary{}
- module.LibraryProperties.BuildStatic = true
- return NewCCLibrary(module, module, common.HostAndDeviceSupported)
- }
- //
- // Shared libraries
- //
- func CCLibrarySharedFactory() (blueprint.Module, []interface{}) {
- module := &CCLibrary{}
- module.LibraryProperties.BuildShared = true
- return NewCCLibrary(module, module, common.HostAndDeviceSupported)
- }
- //
- // Host static library
- //
- func CCLibraryHostStaticFactory() (blueprint.Module, []interface{}) {
- module := &CCLibrary{}
- module.LibraryProperties.BuildStatic = true
- return NewCCLibrary(module, module, common.HostSupported)
- }
- //
- // Host Shared libraries
- //
- func CCLibraryHostSharedFactory() (blueprint.Module, []interface{}) {
- module := &CCLibrary{}
- module.LibraryProperties.BuildShared = true
- return NewCCLibrary(module, module, common.HostSupported)
- }
- //
- // Host Binaries
- //
- func CCBinaryHostFactory() (blueprint.Module, []interface{}) {
- module := &CCBinary{}
- return NewCCBinary(module, module, common.HostSupported)
- }
- //
- // Host Tests
- //
- func CCTestHostFactory() (blueprint.Module, []interface{}) {
- module := &CCTest{}
- return NewCCBinary(&module.CCBinary, module, common.HostSupported)
- }
- //
- // Host Benchmarks
- //
- func CCBenchmarkHostFactory() (blueprint.Module, []interface{}) {
- module := &CCBenchmark{}
- return NewCCBinary(&module.CCBinary, module, common.HostSupported)
- }
- //
- // Device libraries shipped with gcc
- //
- type toolchainLibrary struct {
- CCLibrary
- }
- func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
- // toolchain libraries can't have any dependencies
- return nil
- }
- func (*toolchainLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- // toolchain libraries can't have any dependencies
- return CCDeps{}
- }
- func ToolchainLibraryFactory() (blueprint.Module, []interface{}) {
- module := &toolchainLibrary{}
- module.LibraryProperties.BuildStatic = true
- return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth,
- &module.LibraryProperties)
- }
- func (c *toolchainLibrary) compileModule(ctx common.AndroidModuleContext,
- flags CCFlags, deps CCDeps, objFiles []string) {
- libName := ctx.ModuleName() + staticLibraryExtension
- outputFile := filepath.Join(common.ModuleOutDir(ctx), libName)
- CopyGccLib(ctx, libName, ccFlagsToBuilderFlags(flags), outputFile)
- c.out = outputFile
- ctx.CheckbuildFile(outputFile)
- }
- func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- // 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.AConfig().SrcDir(), version, toolchain.Name())
- }
- func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain,
- ext string, version string) string {
- // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION.
- // We want to translate to just NAME.EXT
- name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
- dir := getNdkLibDir(ctx, toolchain, version)
- return filepath.Join(dir, name+ext)
- }
- type ndkPrebuiltObject struct {
- ccObject
- }
- func (*ndkPrebuiltObject) AndroidDynamicDependencies(
- ctx common.AndroidDynamicDependerModuleContext) []string {
- // NDK objects can't have any dependencies
- return nil
- }
- func (*ndkPrebuiltObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
- // NDK objects can't have any dependencies
- return CCDeps{}
- }
- func NdkPrebuiltObjectFactory() (blueprint.Module, []interface{}) {
- module := &ndkPrebuiltObject{}
- return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth)
- }
- func (c *ndkPrebuiltObject) 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_crt") {
- ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name")
- }
- c.out = ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, c.Properties.Sdk_version)
- }
- func (c *ndkPrebuiltObject) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- // Objects do not get installed.
- }
- var _ ccObjectProvider = (*ndkPrebuiltObject)(nil)
- 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")
- }
- 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.Properties.Sdk_version)
- }
- func (c *ndkPrebuiltLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
- // NDK prebuilt 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.AConfig().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")
- }
- includeDirs := pathtools.PrefixPaths(c.Properties.Export_include_dirs, common.ModuleSrcDir(ctx))
- c.exportFlags = []string{includeDirsToFlags(includeDirs)}
- 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().(ccLinkedInterface); ok {
- var modules []blueprint.Module
- if c.buildStatic() && c.buildShared() {
- modules = mctx.CreateLocalVariations("static", "shared")
- modules[0].(ccLinkedInterface).setStatic(true)
- modules[1].(ccLinkedInterface).setStatic(false)
- } else if c.buildStatic() {
- modules = mctx.CreateLocalVariations("static")
- modules[0].(ccLinkedInterface).setStatic(true)
- } else if c.buildShared() {
- modules = mctx.CreateLocalVariations("shared")
- modules[0].(ccLinkedInterface).setStatic(false)
- } else {
- panic(fmt.Errorf("ccLibrary %q not static or shared", mctx.ModuleName()))
- }
- if _, ok := c.(ccLibraryInterface); ok {
- reuseFrom := modules[0].(ccLibraryInterface)
- for _, m := range modules {
- m.(ccLibraryInterface).setReuseFrom(reuseFrom)
- }
- }
- }
- }
- // lastUniqueElements returns all unique elements of a slice, keeping the last copy of each
- // modifies the slice contents in place, and returns a subslice of the original slice
- func lastUniqueElements(list []string) []string {
- totalSkip := 0
- for i := len(list) - 1; i >= totalSkip; i-- {
- skip := 0
- for j := i - 1; j >= totalSkip; j-- {
- if list[i] == list[j] {
- skip++
- } else {
- list[j+skip] = list[j]
- }
- }
- totalSkip += skip
- }
- return list[totalSkip:]
- }
|