github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/cc/library.go (about)

     1  // Copyright 2016 Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package cc
    16  
    17  import (
    18  	"strings"
    19  
    20  	"github.com/google/blueprint"
    21  	"github.com/google/blueprint/pathtools"
    22  
    23  	"android/soong/android"
    24  )
    25  
    26  type LibraryProperties struct {
    27  	Static struct {
    28  		Srcs   []string `android:"arch_variant"`
    29  		Cflags []string `android:"arch_variant"`
    30  
    31  		Enabled           *bool    `android:"arch_variant"`
    32  		Whole_static_libs []string `android:"arch_variant"`
    33  		Static_libs       []string `android:"arch_variant"`
    34  		Shared_libs       []string `android:"arch_variant"`
    35  	} `android:"arch_variant"`
    36  	Shared struct {
    37  		Srcs   []string `android:"arch_variant"`
    38  		Cflags []string `android:"arch_variant"`
    39  
    40  		Enabled           *bool    `android:"arch_variant"`
    41  		Whole_static_libs []string `android:"arch_variant"`
    42  		Static_libs       []string `android:"arch_variant"`
    43  		Shared_libs       []string `android:"arch_variant"`
    44  	} `android:"arch_variant"`
    45  
    46  	// local file name to pass to the linker as --version_script
    47  	Version_script *string `android:"arch_variant"`
    48  	// local file name to pass to the linker as -unexported_symbols_list
    49  	Unexported_symbols_list *string `android:"arch_variant"`
    50  	// local file name to pass to the linker as -force_symbols_not_weak_list
    51  	Force_symbols_not_weak_list *string `android:"arch_variant"`
    52  	// local file name to pass to the linker as -force_symbols_weak_list
    53  	Force_symbols_weak_list *string `android:"arch_variant"`
    54  
    55  	// rename host libraries to prevent overlap with system installed libraries
    56  	Unique_host_soname *bool
    57  
    58  	Aidl struct {
    59  		// export headers generated from .aidl sources
    60  		Export_aidl_headers *bool
    61  	}
    62  
    63  	Proto struct {
    64  		// export headers generated from .proto sources
    65  		Export_proto_headers *bool
    66  	}
    67  	Target struct {
    68  		Vendor struct {
    69  			// version script for this vendor variant
    70  			Version_script *string `android:"arch_variant"`
    71  		}
    72  	}
    73  
    74  	Static_ndk_lib *bool
    75  }
    76  
    77  type LibraryMutatedProperties struct {
    78  	VariantName string `blueprint:"mutated"`
    79  
    80  	// Build a static variant
    81  	BuildStatic bool `blueprint:"mutated"`
    82  	// Build a shared variant
    83  	BuildShared bool `blueprint:"mutated"`
    84  	// This variant is shared
    85  	VariantIsShared bool `blueprint:"mutated"`
    86  	// This variant is static
    87  	VariantIsStatic bool `blueprint:"mutated"`
    88  }
    89  
    90  type FlagExporterProperties struct {
    91  	// list of directories relative to the Blueprints file that will
    92  	// be added to the include path (using -I) for this module and any module that links
    93  	// against this module.  Directories listed in export_include_dirs do not need to be
    94  	// listed in local_include_dirs.
    95  	Export_include_dirs []string `android:"arch_variant"`
    96  
    97  	Target struct {
    98  		Vendor struct {
    99  			// list of exported include directories, like
   100  			// export_include_dirs, that will be applied to the
   101  			// vendor variant of this library. This will overwrite
   102  			// any other declarations.
   103  			Override_export_include_dirs []string
   104  		}
   105  	}
   106  }
   107  
   108  func init() {
   109  	android.RegisterModuleType("cc_library_static", LibraryStaticFactory)
   110  	android.RegisterModuleType("cc_library_shared", LibrarySharedFactory)
   111  	android.RegisterModuleType("cc_library", LibraryFactory)
   112  	android.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory)
   113  	android.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
   114  	android.RegisterModuleType("cc_library_headers", LibraryHeaderFactory)
   115  }
   116  
   117  // Module factory for combined static + shared libraries, device by default but with possible host
   118  // support
   119  func LibraryFactory() android.Module {
   120  	module, _ := NewLibrary(android.HostAndDeviceSupported)
   121  	return module.Init()
   122  }
   123  
   124  // Module factory for static libraries
   125  func LibraryStaticFactory() android.Module {
   126  	module, library := NewLibrary(android.HostAndDeviceSupported)
   127  	library.BuildOnlyStatic()
   128  	return module.Init()
   129  }
   130  
   131  // Module factory for shared libraries
   132  func LibrarySharedFactory() android.Module {
   133  	module, library := NewLibrary(android.HostAndDeviceSupported)
   134  	library.BuildOnlyShared()
   135  	return module.Init()
   136  }
   137  
   138  // Module factory for host static libraries
   139  func LibraryHostStaticFactory() android.Module {
   140  	module, library := NewLibrary(android.HostSupported)
   141  	library.BuildOnlyStatic()
   142  	return module.Init()
   143  }
   144  
   145  // Module factory for host shared libraries
   146  func LibraryHostSharedFactory() android.Module {
   147  	module, library := NewLibrary(android.HostSupported)
   148  	library.BuildOnlyShared()
   149  	return module.Init()
   150  }
   151  
   152  // Module factory for header-only libraries
   153  func LibraryHeaderFactory() android.Module {
   154  	module, library := NewLibrary(android.HostAndDeviceSupported)
   155  	library.HeaderOnly()
   156  	return module.Init()
   157  }
   158  
   159  type flagExporter struct {
   160  	Properties FlagExporterProperties
   161  
   162  	flags     []string
   163  	flagsDeps android.Paths
   164  }
   165  
   166  func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
   167  	if ctx.useVndk() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
   168  		return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs)
   169  	} else {
   170  		return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
   171  	}
   172  }
   173  
   174  func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) {
   175  	includeDirs := f.exportedIncludes(ctx)
   176  	for _, dir := range includeDirs.Strings() {
   177  		f.flags = append(f.flags, inc+dir)
   178  	}
   179  }
   180  
   181  func (f *flagExporter) reexportFlags(flags []string) {
   182  	f.flags = append(f.flags, flags...)
   183  }
   184  
   185  func (f *flagExporter) reexportDeps(deps android.Paths) {
   186  	f.flagsDeps = append(f.flagsDeps, deps...)
   187  }
   188  
   189  func (f *flagExporter) exportedFlags() []string {
   190  	return f.flags
   191  }
   192  
   193  func (f *flagExporter) exportedFlagsDeps() android.Paths {
   194  	return f.flagsDeps
   195  }
   196  
   197  type exportedFlagsProducer interface {
   198  	exportedFlags() []string
   199  	exportedFlagsDeps() android.Paths
   200  }
   201  
   202  var _ exportedFlagsProducer = (*flagExporter)(nil)
   203  
   204  // libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific
   205  // functionality: static vs. shared linkage, reusing object files for shared libraries
   206  type libraryDecorator struct {
   207  	Properties        LibraryProperties
   208  	MutatedProperties LibraryMutatedProperties
   209  
   210  	// For reusing static library objects for shared library
   211  	reuseObjects       Objects
   212  	reuseExportedFlags []string
   213  	reuseExportedDeps  android.Paths
   214  
   215  	// table-of-contents file to optimize out relinking when possible
   216  	tocFile android.OptionalPath
   217  
   218  	flagExporter
   219  	stripper
   220  	relocationPacker
   221  
   222  	// If we're used as a whole_static_lib, our missing dependencies need
   223  	// to be given
   224  	wholeStaticMissingDeps []string
   225  
   226  	// For whole_static_libs
   227  	objects Objects
   228  
   229  	// Uses the module's name if empty, but can be overridden. Does not include
   230  	// shlib suffix.
   231  	libName string
   232  
   233  	sanitize *sanitize
   234  
   235  	sabi *sabi
   236  
   237  	// Output archive of gcno coverage information files
   238  	coverageOutputFile android.OptionalPath
   239  
   240  	// linked Source Abi Dump
   241  	sAbiOutputFile android.OptionalPath
   242  
   243  	// Source Abi Diff
   244  	sAbiDiff android.OptionalPath
   245  
   246  	// Location of the static library in the sysroot. Empty if the library is
   247  	// not included in the NDK.
   248  	ndkSysrootPath android.Path
   249  
   250  	// Decorated interafaces
   251  	*baseCompiler
   252  	*baseLinker
   253  	*baseInstaller
   254  }
   255  
   256  func (library *libraryDecorator) linkerProps() []interface{} {
   257  	var props []interface{}
   258  	props = append(props, library.baseLinker.linkerProps()...)
   259  	return append(props,
   260  		&library.Properties,
   261  		&library.MutatedProperties,
   262  		&library.flagExporter.Properties,
   263  		&library.stripper.StripProperties,
   264  		&library.relocationPacker.Properties)
   265  }
   266  
   267  func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
   268  	flags = library.baseLinker.linkerFlags(ctx, flags)
   269  
   270  	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
   271  	// all code is position independent, and then those warnings get promoted to
   272  	// errors.
   273  	if !ctx.Windows() {
   274  		flags.CFlags = append(flags.CFlags, "-fPIC")
   275  	}
   276  
   277  	if library.static() {
   278  		flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...)
   279  	} else if library.shared() {
   280  		flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...)
   281  	}
   282  
   283  	if library.shared() {
   284  		libName := library.getLibName(ctx)
   285  		// GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
   286  		sharedFlag := "-Wl,-shared"
   287  		if flags.Clang || ctx.Host() {
   288  			sharedFlag = "-shared"
   289  		}
   290  		var f []string
   291  		if ctx.toolchain().Bionic() {
   292  			f = append(f,
   293  				"-nostdlib",
   294  				"-Wl,--gc-sections",
   295  			)
   296  		}
   297  
   298  		if ctx.Darwin() {
   299  			f = append(f,
   300  				"-dynamiclib",
   301  				"-single_module",
   302  				"-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
   303  			)
   304  			if ctx.Arch().ArchType == android.X86 {
   305  				f = append(f,
   306  					"-read_only_relocs suppress",
   307  				)
   308  			}
   309  		} else {
   310  			f = append(f,
   311  				sharedFlag,
   312  				"-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
   313  		}
   314  
   315  		flags.LdFlags = append(f, flags.LdFlags...)
   316  	}
   317  
   318  	return flags
   319  }
   320  
   321  func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
   322  	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
   323  	if len(exportIncludeDirs) > 0 {
   324  		f := includeDirsToFlags(exportIncludeDirs)
   325  		flags.GlobalFlags = append(flags.GlobalFlags, f)
   326  		flags.YasmFlags = append(flags.YasmFlags, f)
   327  	}
   328  
   329  	return library.baseCompiler.compilerFlags(ctx, flags, deps)
   330  }
   331  
   332  func extractExportIncludesFromFlags(flags []string) []string {
   333  	// This method is used in the  generation of rules which produce
   334  	// abi-dumps for source files. Exported headers are needed to infer the
   335  	// abi exported by a library and filter out the rest of the abi dumped
   336  	// from a source. We extract the include flags exported by a library.
   337  	// This includes the flags exported which are re-exported from static
   338  	// library dependencies, exported header library dependencies and
   339  	// generated header dependencies. -isystem headers are not included
   340  	// since for bionic libraries, abi-filtering is taken care of by version
   341  	// scripts.
   342  	var exportedIncludes []string
   343  	for _, flag := range flags {
   344  		if strings.HasPrefix(flag, "-I") {
   345  			exportedIncludes = append(exportedIncludes, flag)
   346  		}
   347  	}
   348  	return exportedIncludes
   349  }
   350  
   351  func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
   352  	if !library.buildShared() && !library.buildStatic() {
   353  		if len(library.baseCompiler.Properties.Srcs) > 0 {
   354  			ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs")
   355  		}
   356  		if len(library.Properties.Static.Srcs) > 0 {
   357  			ctx.PropertyErrorf("static.srcs", "cc_library_headers must not have any srcs")
   358  		}
   359  		if len(library.Properties.Shared.Srcs) > 0 {
   360  			ctx.PropertyErrorf("shared.srcs", "cc_library_headers must not have any srcs")
   361  		}
   362  		return Objects{}
   363  	}
   364  	if ctx.createVndkSourceAbiDump() || library.sabi.Properties.CreateSAbiDumps {
   365  		exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
   366  		var SourceAbiFlags []string
   367  		for _, dir := range exportIncludeDirs.Strings() {
   368  			SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
   369  		}
   370  		for _, reexportedInclude := range extractExportIncludesFromFlags(library.sabi.Properties.ReexportedIncludeFlags) {
   371  			SourceAbiFlags = append(SourceAbiFlags, reexportedInclude)
   372  		}
   373  		flags.SAbiFlags = SourceAbiFlags
   374  		total_length := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + len(library.Properties.Shared.Srcs) +
   375  			len(library.Properties.Static.Srcs)
   376  		if total_length > 0 {
   377  			flags.SAbiDump = true
   378  		}
   379  	}
   380  	objs := library.baseCompiler.compile(ctx, flags, deps)
   381  	library.reuseObjects = objs
   382  	buildFlags := flagsToBuilderFlags(flags)
   383  
   384  	if library.static() {
   385  		srcs := android.PathsForModuleSrc(ctx, library.Properties.Static.Srcs)
   386  		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary,
   387  			srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
   388  	} else if library.shared() {
   389  		srcs := android.PathsForModuleSrc(ctx, library.Properties.Shared.Srcs)
   390  		objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary,
   391  			srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
   392  	}
   393  
   394  	return objs
   395  }
   396  
   397  type libraryInterface interface {
   398  	getWholeStaticMissingDeps() []string
   399  	static() bool
   400  	objs() Objects
   401  	reuseObjs() (Objects, []string, android.Paths)
   402  	toc() android.OptionalPath
   403  
   404  	// Returns true if the build options for the module have selected a static or shared build
   405  	buildStatic() bool
   406  	buildShared() bool
   407  
   408  	// Sets whether a specific variant is static or shared
   409  	setStatic()
   410  	setShared()
   411  }
   412  
   413  func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
   414  	name := library.libName
   415  	if name == "" {
   416  		name = ctx.baseModuleName()
   417  	}
   418  
   419  	if ctx.isVndkExt() {
   420  		name = ctx.getVndkExtendsModuleName()
   421  	}
   422  
   423  	if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
   424  		if !strings.HasSuffix(name, "-host") {
   425  			name = name + "-host"
   426  		}
   427  	}
   428  
   429  	return name + library.MutatedProperties.VariantName
   430  }
   431  
   432  func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) {
   433  	location := InstallInSystem
   434  	if library.sanitize.inSanitizerDir() {
   435  		location = InstallInSanitizerDir
   436  	}
   437  	library.baseInstaller.location = location
   438  
   439  	library.baseLinker.linkerInit(ctx)
   440  
   441  	library.relocationPacker.packingInit(ctx)
   442  }
   443  
   444  func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
   445  	deps = library.baseLinker.linkerDeps(ctx, deps)
   446  
   447  	if library.static() {
   448  		deps.WholeStaticLibs = append(deps.WholeStaticLibs,
   449  			library.Properties.Static.Whole_static_libs...)
   450  		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
   451  		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
   452  	} else if library.shared() {
   453  		if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
   454  			if !ctx.useSdk() {
   455  				deps.CrtBegin = "crtbegin_so"
   456  				deps.CrtEnd = "crtend_so"
   457  			} else {
   458  				// TODO(danalbert): Add generation of crt objects.
   459  				// For `sdk_version: "current"`, we don't actually have a
   460  				// freshly generated set of CRT objects. Use the last stable
   461  				// version.
   462  				version := ctx.sdkVersion()
   463  				if version == "current" {
   464  					version = getCurrentNdkPrebuiltVersion(ctx)
   465  				}
   466  				deps.CrtBegin = "ndk_crtbegin_so." + version
   467  				deps.CrtEnd = "ndk_crtend_so." + version
   468  			}
   469  		}
   470  		deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
   471  		deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
   472  		deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
   473  	}
   474  	if ctx.useVndk() {
   475  		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
   476  		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
   477  		deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
   478  	}
   479  
   480  	android.ExtractSourceDeps(ctx, library.Properties.Version_script)
   481  	android.ExtractSourceDeps(ctx, library.Properties.Unexported_symbols_list)
   482  	android.ExtractSourceDeps(ctx, library.Properties.Force_symbols_not_weak_list)
   483  	android.ExtractSourceDeps(ctx, library.Properties.Force_symbols_weak_list)
   484  	android.ExtractSourceDeps(ctx, library.Properties.Target.Vendor.Version_script)
   485  
   486  	return deps
   487  }
   488  
   489  func (library *libraryDecorator) linkStatic(ctx ModuleContext,
   490  	flags Flags, deps PathDeps, objs Objects) android.Path {
   491  
   492  	library.objects = deps.WholeStaticLibObjs.Copy()
   493  	library.objects = library.objects.Append(objs)
   494  
   495  	fileName := ctx.ModuleName() + library.MutatedProperties.VariantName + staticLibraryExtension
   496  	outputFile := android.PathForModuleOut(ctx, fileName)
   497  	builderFlags := flagsToBuilderFlags(flags)
   498  
   499  	if Bool(library.baseLinker.Properties.Use_version_lib) && ctx.Host() {
   500  		versionedOutputFile := outputFile
   501  		outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
   502  		library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
   503  	}
   504  
   505  	TransformObjToStaticLib(ctx, library.objects.objFiles, builderFlags, outputFile, objs.tidyFiles)
   506  
   507  	library.coverageOutputFile = TransformCoverageFilesToLib(ctx, library.objects, builderFlags,
   508  		ctx.ModuleName()+library.MutatedProperties.VariantName)
   509  
   510  	library.wholeStaticMissingDeps = ctx.GetMissingDependencies()
   511  
   512  	ctx.CheckbuildFile(outputFile)
   513  
   514  	return outputFile
   515  }
   516  
   517  func (library *libraryDecorator) linkShared(ctx ModuleContext,
   518  	flags Flags, deps PathDeps, objs Objects) android.Path {
   519  
   520  	var linkerDeps android.Paths
   521  	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
   522  
   523  	versionScript := ctx.ExpandOptionalSource(library.Properties.Version_script, "version_script")
   524  	unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
   525  	forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
   526  	forceWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_weak_list, "force_symbols_weak_list")
   527  	if ctx.useVndk() && library.Properties.Target.Vendor.Version_script != nil {
   528  		versionScript = ctx.ExpandOptionalSource(library.Properties.Target.Vendor.Version_script, "target.vendor.version_script")
   529  	}
   530  	if !ctx.Darwin() {
   531  		if versionScript.Valid() {
   532  			flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
   533  			linkerDeps = append(linkerDeps, versionScript.Path())
   534  			if library.sanitize.isSanitizerEnabled(cfi) {
   535  				cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath)
   536  				flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+cfiExportsMap.String())
   537  				linkerDeps = append(linkerDeps, cfiExportsMap)
   538  			}
   539  		}
   540  		if unexportedSymbols.Valid() {
   541  			ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
   542  		}
   543  		if forceNotWeakSymbols.Valid() {
   544  			ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin")
   545  		}
   546  		if forceWeakSymbols.Valid() {
   547  			ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin")
   548  		}
   549  	} else {
   550  		if versionScript.Valid() {
   551  			ctx.PropertyErrorf("version_script", "Not supported on Darwin")
   552  		}
   553  		if unexportedSymbols.Valid() {
   554  			flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String())
   555  			linkerDeps = append(linkerDeps, unexportedSymbols.Path())
   556  		}
   557  		if forceNotWeakSymbols.Valid() {
   558  			flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String())
   559  			linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path())
   560  		}
   561  		if forceWeakSymbols.Valid() {
   562  			flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String())
   563  			linkerDeps = append(linkerDeps, forceWeakSymbols.Path())
   564  		}
   565  	}
   566  
   567  	fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
   568  	outputFile := android.PathForModuleOut(ctx, fileName)
   569  	ret := outputFile
   570  
   571  	builderFlags := flagsToBuilderFlags(flags)
   572  
   573  	if !ctx.Darwin() && !ctx.Windows() {
   574  		// Optimize out relinking against shared libraries whose interface hasn't changed by
   575  		// depending on a table of contents file instead of the library itself.
   576  		tocPath := outputFile.RelPathString()
   577  		tocPath = pathtools.ReplaceExtension(tocPath, flags.Toolchain.ShlibSuffix()[1:]+".toc")
   578  		tocFile := android.PathForOutput(ctx, tocPath)
   579  		library.tocFile = android.OptionalPathForPath(tocFile)
   580  		TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags)
   581  	}
   582  
   583  	if library.relocationPacker.needsPacking(ctx) {
   584  		packedOutputFile := outputFile
   585  		outputFile = android.PathForModuleOut(ctx, "unpacked", fileName)
   586  		library.relocationPacker.pack(ctx, outputFile, packedOutputFile, builderFlags)
   587  	}
   588  
   589  	if library.stripper.needsStrip(ctx) {
   590  		strippedOutputFile := outputFile
   591  		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
   592  		library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
   593  	}
   594  
   595  	if Bool(library.baseLinker.Properties.Use_version_lib) && ctx.Host() {
   596  		versionedOutputFile := outputFile
   597  		outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
   598  		library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
   599  	}
   600  
   601  	sharedLibs := deps.SharedLibs
   602  	sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
   603  
   604  	// TODO(danalbert): Clean this up when soong supports prebuilts.
   605  	if strings.HasPrefix(ctx.selectedStl(), "ndk_libc++") {
   606  		libDir := getNdkStlLibDir(ctx, "libc++")
   607  
   608  		if strings.HasSuffix(ctx.selectedStl(), "_shared") {
   609  			deps.StaticLibs = append(deps.StaticLibs,
   610  				libDir.Join(ctx, "libandroid_support.a"))
   611  		} else {
   612  			deps.StaticLibs = append(deps.StaticLibs,
   613  				libDir.Join(ctx, "libc++abi.a"),
   614  				libDir.Join(ctx, "libandroid_support.a"))
   615  		}
   616  
   617  		if ctx.Arch().ArchType == android.Arm {
   618  			deps.StaticLibs = append(deps.StaticLibs,
   619  				libDir.Join(ctx, "libunwind.a"))
   620  		}
   621  	}
   622  
   623  	linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
   624  	linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
   625  	linkerDeps = append(linkerDeps, objs.tidyFiles...)
   626  
   627  	TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
   628  		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
   629  		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
   630  
   631  	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
   632  	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
   633  
   634  	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...)
   635  	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
   636  
   637  	library.coverageOutputFile = TransformCoverageFilesToLib(ctx, objs, builderFlags, library.getLibName(ctx))
   638  	library.linkSAbiDumpFiles(ctx, objs, fileName, ret)
   639  
   640  	return ret
   641  }
   642  
   643  func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
   644  	//Also take into account object re-use.
   645  	if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() {
   646  		vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
   647  		if ver := ctx.DeviceConfig().VndkVersion(); ver != "" && ver != "current" {
   648  			vndkVersion = ver
   649  		}
   650  
   651  		refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, vndkVsNdk(ctx), true)
   652  		exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
   653  		var SourceAbiFlags []string
   654  		for _, dir := range exportIncludeDirs.Strings() {
   655  			SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
   656  		}
   657  		for _, reexportedInclude := range extractExportIncludesFromFlags(library.sabi.Properties.ReexportedIncludeFlags) {
   658  			SourceAbiFlags = append(SourceAbiFlags, reexportedInclude)
   659  		}
   660  		exportedHeaderFlags := strings.Join(SourceAbiFlags, " ")
   661  		library.sAbiOutputFile = TransformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags)
   662  		if refSourceDumpFile.Valid() {
   663  			unzippedRefDump := UnzipRefDump(ctx, refSourceDumpFile.Path(), fileName)
   664  			library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
   665  				unzippedRefDump, fileName, exportedHeaderFlags, ctx.isVndkExt())
   666  		}
   667  	}
   668  }
   669  
   670  func vndkVsNdk(ctx ModuleContext) bool {
   671  	if inList(ctx.baseModuleName(), llndkLibraries) {
   672  		return false
   673  	}
   674  	return true
   675  }
   676  
   677  func (library *libraryDecorator) link(ctx ModuleContext,
   678  	flags Flags, deps PathDeps, objs Objects) android.Path {
   679  
   680  	objs = deps.Objs.Copy().Append(objs)
   681  	var out android.Path
   682  	if library.static() || library.header() {
   683  		out = library.linkStatic(ctx, flags, deps, objs)
   684  	} else {
   685  		out = library.linkShared(ctx, flags, deps, objs)
   686  	}
   687  
   688  	library.exportIncludes(ctx, "-I")
   689  	library.reexportFlags(deps.ReexportedFlags)
   690  	library.reexportDeps(deps.ReexportedFlagsDeps)
   691  
   692  	if Bool(library.Properties.Aidl.Export_aidl_headers) {
   693  		if library.baseCompiler.hasSrcExt(".aidl") {
   694  			flags := []string{
   695  				"-I" + android.PathForModuleGen(ctx, "aidl").String(),
   696  			}
   697  			library.reexportFlags(flags)
   698  			library.reuseExportedFlags = append(library.reuseExportedFlags, flags...)
   699  			library.reexportDeps(library.baseCompiler.pathDeps) // TODO: restrict to aidl deps
   700  			library.reuseExportedDeps = append(library.reuseExportedDeps, library.baseCompiler.pathDeps...)
   701  		}
   702  	}
   703  
   704  	if Bool(library.Properties.Proto.Export_proto_headers) {
   705  		if library.baseCompiler.hasSrcExt(".proto") {
   706  			includes := []string{}
   707  			if flags.ProtoRoot {
   708  				includes = append(includes, "-I"+android.ProtoSubDir(ctx).String())
   709  			}
   710  			includes = append(includes, "-I"+android.ProtoDir(ctx).String())
   711  			library.reexportFlags(includes)
   712  			library.reuseExportedFlags = append(library.reuseExportedFlags, includes...)
   713  			library.reexportDeps(library.baseCompiler.pathDeps) // TODO: restrict to proto deps
   714  			library.reuseExportedDeps = append(library.reuseExportedDeps, library.baseCompiler.pathDeps...)
   715  		}
   716  	}
   717  
   718  	return out
   719  }
   720  
   721  func (library *libraryDecorator) buildStatic() bool {
   722  	return library.MutatedProperties.BuildStatic &&
   723  		(library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled)
   724  }
   725  
   726  func (library *libraryDecorator) buildShared() bool {
   727  	return library.MutatedProperties.BuildShared &&
   728  		(library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled)
   729  }
   730  
   731  func (library *libraryDecorator) getWholeStaticMissingDeps() []string {
   732  	return library.wholeStaticMissingDeps
   733  }
   734  
   735  func (library *libraryDecorator) objs() Objects {
   736  	return library.objects
   737  }
   738  
   739  func (library *libraryDecorator) reuseObjs() (Objects, []string, android.Paths) {
   740  	return library.reuseObjects, library.reuseExportedFlags, library.reuseExportedDeps
   741  }
   742  
   743  func (library *libraryDecorator) toc() android.OptionalPath {
   744  	return library.tocFile
   745  }
   746  
   747  func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
   748  	if library.shared() {
   749  		if ctx.Device() && ctx.useVndk() {
   750  			if ctx.isVndkSp() {
   751  				library.baseInstaller.subDir = "vndk-sp"
   752  			} else if ctx.isVndk() {
   753  				library.baseInstaller.subDir = "vndk"
   754  			}
   755  
   756  			// Append a version to vndk or vndk-sp directories on the system partition.
   757  			if ctx.isVndk() && !ctx.isVndkExt() {
   758  				vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
   759  				if vndkVersion != "current" && vndkVersion != "" {
   760  					library.baseInstaller.subDir += "-" + vndkVersion
   761  				}
   762  			}
   763  		}
   764  		library.baseInstaller.install(ctx, file)
   765  	}
   766  
   767  	if Bool(library.Properties.Static_ndk_lib) && library.static() &&
   768  		!ctx.useVndk() && ctx.Device() &&
   769  		library.sanitize.isUnsanitizedVariant() {
   770  		installPath := getNdkSysrootBase(ctx).Join(
   771  			ctx, "usr/lib", ctx.toolchain().ClangTriple(), file.Base())
   772  
   773  		ctx.ModuleBuild(pctx, android.ModuleBuildParams{
   774  			Rule:        android.Cp,
   775  			Description: "install " + installPath.Base(),
   776  			Output:      installPath,
   777  			Input:       file,
   778  		})
   779  
   780  		library.ndkSysrootPath = installPath
   781  	}
   782  }
   783  
   784  func (library *libraryDecorator) static() bool {
   785  	return library.MutatedProperties.VariantIsStatic
   786  }
   787  
   788  func (library *libraryDecorator) shared() bool {
   789  	return library.MutatedProperties.VariantIsShared
   790  }
   791  
   792  func (library *libraryDecorator) header() bool {
   793  	return !library.static() && !library.shared()
   794  }
   795  
   796  func (library *libraryDecorator) setStatic() {
   797  	library.MutatedProperties.VariantIsStatic = true
   798  	library.MutatedProperties.VariantIsShared = false
   799  }
   800  
   801  func (library *libraryDecorator) setShared() {
   802  	library.MutatedProperties.VariantIsStatic = false
   803  	library.MutatedProperties.VariantIsShared = true
   804  }
   805  
   806  func (library *libraryDecorator) BuildOnlyStatic() {
   807  	library.MutatedProperties.BuildShared = false
   808  }
   809  
   810  func (library *libraryDecorator) BuildOnlyShared() {
   811  	library.MutatedProperties.BuildStatic = false
   812  }
   813  
   814  func (library *libraryDecorator) HeaderOnly() {
   815  	library.MutatedProperties.BuildShared = false
   816  	library.MutatedProperties.BuildStatic = false
   817  }
   818  
   819  func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
   820  	module := newModule(hod, android.MultilibBoth)
   821  
   822  	library := &libraryDecorator{
   823  		MutatedProperties: LibraryMutatedProperties{
   824  			BuildShared: true,
   825  			BuildStatic: true,
   826  		},
   827  		baseCompiler:  NewBaseCompiler(),
   828  		baseLinker:    NewBaseLinker(),
   829  		baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem),
   830  		sanitize:      module.sanitize,
   831  		sabi:          module.sabi,
   832  	}
   833  
   834  	module.compiler = library
   835  	module.linker = library
   836  	module.installer = library
   837  
   838  	return module, library
   839  }
   840  
   841  // connects a shared library to a static library in order to reuse its .o files to avoid
   842  // compiling source files twice.
   843  func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) {
   844  	if staticCompiler, ok := static.compiler.(*libraryDecorator); ok {
   845  		sharedCompiler := shared.compiler.(*libraryDecorator)
   846  		if len(staticCompiler.Properties.Static.Cflags) == 0 &&
   847  			len(sharedCompiler.Properties.Shared.Cflags) == 0 {
   848  
   849  			mctx.AddInterVariantDependency(reuseObjTag, shared, static)
   850  			sharedCompiler.baseCompiler.Properties.OriginalSrcs =
   851  				sharedCompiler.baseCompiler.Properties.Srcs
   852  			sharedCompiler.baseCompiler.Properties.Srcs = nil
   853  			sharedCompiler.baseCompiler.Properties.Generated_sources = nil
   854  		}
   855  	}
   856  }
   857  
   858  func linkageMutator(mctx android.BottomUpMutatorContext) {
   859  	if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
   860  		if library, ok := m.linker.(libraryInterface); ok {
   861  			var modules []blueprint.Module
   862  			if library.buildStatic() && library.buildShared() {
   863  				modules = mctx.CreateLocalVariations("static", "shared")
   864  				static := modules[0].(*Module)
   865  				shared := modules[1].(*Module)
   866  
   867  				static.linker.(libraryInterface).setStatic()
   868  				shared.linker.(libraryInterface).setShared()
   869  
   870  				reuseStaticLibrary(mctx, static, shared)
   871  
   872  			} else if library.buildStatic() {
   873  				modules = mctx.CreateLocalVariations("static")
   874  				modules[0].(*Module).linker.(libraryInterface).setStatic()
   875  			} else if library.buildShared() {
   876  				modules = mctx.CreateLocalVariations("shared")
   877  				modules[0].(*Module).linker.(libraryInterface).setShared()
   878  			}
   879  		}
   880  	}
   881  }