Merge "Separate exported includes out of flags"
diff --git a/cc/binary.go b/cc/binary.go
index 9bb0b16..941f131 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -384,7 +384,7 @@
 
 	TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
 		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
-		builderFlags, outputFile)
+		builderFlags, outputFile, nil)
 
 	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
 	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
diff --git a/cc/builder.go b/cc/builder.go
index d2727b3..7cf5c29 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -26,6 +26,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
 
 	"android/soong/android"
 	"android/soong/cc/config"
@@ -611,7 +612,7 @@
 // and shared libraries, to a shared library (.so) or dynamic executable
 func TransformObjToDynamicBinary(ctx android.ModuleContext,
 	objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths,
-	crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath) {
+	crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath, implicitOutputs android.WritablePaths) {
 
 	ldCmd := "${config.ClangBin}/clang++"
 
@@ -648,7 +649,11 @@
 	}
 
 	for _, lib := range sharedLibs {
-		libFlagsList = append(libFlagsList, lib.String())
+		libFile := lib.String()
+		if ctx.Windows() {
+			libFile = pathtools.ReplaceExtension(libFile, "lib")
+		}
+		libFlagsList = append(libFlagsList, libFile)
 	}
 
 	deps = append(deps, staticLibs...)
@@ -659,11 +664,12 @@
 	}
 
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        ld,
-		Description: "link " + outputFile.Base(),
-		Output:      outputFile,
-		Inputs:      objFiles,
-		Implicits:   deps,
+		Rule:            ld,
+		Description:     "link " + outputFile.Base(),
+		Output:          outputFile,
+		ImplicitOutputs: implicitOutputs,
+		Inputs:          objFiles,
+		Implicits:       deps,
 		Args: map[string]string{
 			"ldCmd":    ldCmd,
 			"crtBegin": crtBegin.String(),
diff --git a/cc/compiler.go b/cc/compiler.go
index 7667ae7..fd6184b 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -225,11 +225,6 @@
 		deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
 	}
 
-	if compiler.hasSrcExt(".sysprop") {
-		deps.HeaderLibs = append(deps.HeaderLibs, "libbase_headers")
-		deps.SharedLibs = append(deps.SharedLibs, "liblog")
-	}
-
 	if Bool(compiler.Properties.Openmp) {
 		deps.StaticLibs = append(deps.StaticLibs, "libomp")
 	}
diff --git a/cc/library.go b/cc/library.go
index 304a620..725208a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -386,9 +386,10 @@
 				)
 			}
 		} else {
-			f = append(f,
-				"-shared",
-				"-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+			f = append(f, "-shared")
+			if !ctx.Windows() {
+				f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+			}
 		}
 
 		flags.LdFlags = append(f, flags.LdFlags...)
@@ -703,6 +704,14 @@
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	ret := outputFile
 
+	var implicitOutputs android.WritablePaths
+	if ctx.Windows() {
+		importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "lib"))
+
+		flags.LdFlags = append(flags.LdFlags, "-Wl,--out-implib="+importLibraryPath.String())
+		implicitOutputs = append(implicitOutputs, importLibraryPath)
+	}
+
 	builderFlags := flagsToBuilderFlags(flags)
 
 	// Optimize out relinking against shared libraries whose interface hasn't changed by
@@ -754,7 +763,7 @@
 
 	TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
 		deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
-		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
+		linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs)
 
 	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
 	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
diff --git a/cc/linker.go b/cc/linker.go
index fafefdc..dda2fcb 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -295,10 +295,6 @@
 	if ctx.Darwin() {
 		return false
 	}
-	// http://b/110800681 - lld cannot link Android's Windows modules yet.
-	if ctx.Windows() {
-		return false
-	}
 	if linker.Properties.Use_clang_lld != nil {
 		return Bool(linker.Properties.Use_clang_lld)
 	}
@@ -352,7 +348,7 @@
 			// darwin defaults to treating undefined symbols as errors
 			flags.LdFlags = append(flags.LdFlags, "-Wl,-undefined,dynamic_lookup")
 		}
-	} else if !ctx.Darwin() {
+	} else if !ctx.Darwin() && !ctx.Windows() {
 		flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
 	}
 
@@ -389,7 +385,7 @@
 
 	flags.LdFlags = append(flags.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)
 
-	if ctx.Host() {
+	if ctx.Host() && !ctx.Windows() {
 		rpath_prefix := `\$$ORIGIN/`
 		if ctx.Darwin() {
 			rpath_prefix = "@loader_path/"
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index e8208ae..8290103 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -134,6 +134,7 @@
 	if !Bool(stub.Properties.Unversioned) {
 		linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
 		flags.LdFlags = append(flags.LdFlags, linkerScriptFlag)
+		flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath)
 	}
 
 	if len(stub.Properties.Export_preprocessed_headers) > 0 {
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 44f773c..969cb3f 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -337,6 +337,7 @@
 	if useVersionScript {
 		linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
 		flags.LdFlags = append(flags.LdFlags, linkerScriptFlag)
+		flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath)
 	}
 
 	return stub.libraryDecorator.link(ctx, flags, deps, objs)
diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go
index 5738d25..f0de267 100644
--- a/cc/vendor_public_library.go
+++ b/cc/vendor_public_library.go
@@ -125,6 +125,7 @@
 	if !Bool(stub.Properties.Unversioned) {
 		linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
 		flags.LdFlags = append(flags.LdFlags, linkerScriptFlag)
+		flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath)
 	}
 	return stub.libraryDecorator.link(ctx, flags, deps, objs)
 }
diff --git a/cmd/zipsync/zipsync.go b/cmd/zipsync/zipsync.go
index ea755f5..a6023d3 100644
--- a/cmd/zipsync/zipsync.go
+++ b/cmd/zipsync/zipsync.go
@@ -30,6 +30,7 @@
 	outputDir  = flag.String("d", "", "output dir")
 	outputFile = flag.String("l", "", "output list file")
 	filter     = flag.String("f", "", "optional filter pattern")
+	zipPrefix  = flag.String("zip-prefix", "", "optional prefix within the zip file to extract, stripping the prefix")
 )
 
 func must(err error) {
@@ -77,6 +78,10 @@
 	var files []string
 	seen := make(map[string]string)
 
+	if *zipPrefix != "" {
+		*zipPrefix = filepath.Clean(*zipPrefix) + "/"
+	}
+
 	for _, input := range inputs {
 		reader, err := zip.OpenReader(input)
 		if err != nil {
@@ -85,23 +90,30 @@
 		defer reader.Close()
 
 		for _, f := range reader.File {
+			name := f.Name
+			if *zipPrefix != "" {
+				if !strings.HasPrefix(name, *zipPrefix) {
+					continue
+				}
+				name = strings.TrimPrefix(name, *zipPrefix)
+			}
 			if *filter != "" {
-				if match, err := filepath.Match(*filter, filepath.Base(f.Name)); err != nil {
+				if match, err := filepath.Match(*filter, filepath.Base(name)); err != nil {
 					log.Fatal(err)
 				} else if !match {
 					continue
 				}
 			}
-			if filepath.IsAbs(f.Name) {
-				log.Fatalf("%q in %q is an absolute path", f.Name, input)
+			if filepath.IsAbs(name) {
+				log.Fatalf("%q in %q is an absolute path", name, input)
 			}
 
-			if prev, exists := seen[f.Name]; exists {
-				log.Fatalf("%q found in both %q and %q", f.Name, prev, input)
+			if prev, exists := seen[name]; exists {
+				log.Fatalf("%q found in both %q and %q", name, prev, input)
 			}
-			seen[f.Name] = input
+			seen[name] = input
 
-			filename := filepath.Join(*outputDir, f.Name)
+			filename := filepath.Join(*outputDir, name)
 			if f.FileInfo().IsDir() {
 				must(os.MkdirAll(filename, f.FileInfo().Mode()))
 			} else {
diff --git a/java/aapt2.go b/java/aapt2.go
index bcc8e97..a815160 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -94,32 +94,20 @@
 	return ret
 }
 
-func aapt2CompileDirs(ctx android.ModuleContext, flata android.WritablePath, dirs android.Paths, deps android.Paths) {
-	ctx.Build(pctx, android.BuildParams{
-		Rule:        aapt2CompileRule,
-		Description: "aapt2 compile dirs",
-		Implicits:   deps,
-		Output:      flata,
-		Args: map[string]string{
-			"outDir": flata.String(),
-			// Always set --pseudo-localize, it will be stripped out later for release
-			// builds that don't want it.
-			"cFlags": "--pseudo-localize " + android.JoinWithPrefix(dirs.Strings(), "--dir "),
-		},
-	})
-}
-
 var aapt2CompileZipRule = pctx.AndroidStaticRule("aapt2CompileZip",
 	blueprint.RuleParams{
-		Command: `${config.ZipSyncCmd} -d $resZipDir $in && ` +
+		Command: `${config.ZipSyncCmd} -d $resZipDir $zipSyncFlags $in && ` +
 			`${config.Aapt2Cmd} compile -o $out $cFlags --legacy --dir $resZipDir`,
 		CommandDeps: []string{
 			"${config.Aapt2Cmd}",
 			"${config.ZipSyncCmd}",
 		},
-	}, "cFlags", "resZipDir")
+	}, "cFlags", "resZipDir", "zipSyncFlags")
 
-func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path) {
+func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path, zipPrefix string) {
+	if zipPrefix != "" {
+		zipPrefix = "--zip-prefix " + zipPrefix
+	}
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        aapt2CompileZipRule,
 		Description: "aapt2 compile zip",
@@ -128,8 +116,9 @@
 		Args: map[string]string{
 			// Always set --pseudo-localize, it will be stripped out later for release
 			// builds that don't want it.
-			"cFlags":    "--pseudo-localize",
-			"resZipDir": android.PathForModuleOut(ctx, "aapt2", "reszip", flata.Base()).String(),
+			"cFlags":       "--pseudo-localize",
+			"resZipDir":    android.PathForModuleOut(ctx, "aapt2", "reszip", flata.Base()).String(),
+			"zipSyncFlags": zipPrefix,
 		},
 	})
 }
diff --git a/java/aar.go b/java/aar.go
index 1b84a47..1e8e6d8 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -245,7 +245,7 @@
 
 	for i, zip := range resZips {
 		flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
-		aapt2CompileZip(ctx, flata, zip)
+		aapt2CompileZip(ctx, flata, zip, "")
 		compiledResDirs = append(compiledResDirs, android.Paths{flata})
 	}
 
@@ -556,13 +556,13 @@
 }
 
 // Unzip an AAR into its constituent files and directories.  Any files in Outputs that don't exist in the AAR will be
-// touched to create an empty file, and any directories in $expectedDirs will be created.
+// touched to create an empty file. The res directory is not extracted, as it will be extracted in its own rule.
 var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
 	blueprint.RuleParams{
-		Command: `rm -rf $outDir && mkdir -p $outDir $expectedDirs && ` +
-			`unzip -qo -d $outDir $in && touch $out`,
+		Command: `rm -rf $outDir && mkdir -p $outDir && ` +
+			`unzip -qo -d $outDir $in && rm -rf $outDir/res && touch $out`,
 	},
-	"expectedDirs", "outDir")
+	"outDir")
 
 func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	if len(a.properties.Aars) != 1 {
@@ -580,7 +580,6 @@
 	}
 
 	extractedAARDir := android.PathForModuleOut(ctx, "aar")
-	extractedResDir := extractedAARDir.Join(ctx, "res")
 	a.classpathFile = extractedAARDir.Join(ctx, "classes.jar")
 	a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
 	a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
@@ -591,16 +590,13 @@
 		Outputs:     android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest},
 		Description: "unzip AAR",
 		Args: map[string]string{
-			"expectedDirs": extractedResDir.String(),
-			"outDir":       extractedAARDir.String(),
+			"outDir": extractedAARDir.String(),
 		},
 	})
 
 	compiledResDir := android.PathForModuleOut(ctx, "flat-res")
-	aaptCompileDeps := android.Paths{a.classpathFile}
-	aaptCompileDirs := android.Paths{extractedResDir}
 	flata := compiledResDir.Join(ctx, "gen_res.flata")
-	aapt2CompileDirs(ctx, flata, aaptCompileDirs, aaptCompileDeps)
+	aapt2CompileZip(ctx, flata, aar, "res")
 
 	a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
 	srcJar := android.PathForModuleGen(ctx, "R.jar")
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 3f2709e..86061c6 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -123,6 +123,8 @@
 		Sysprop          struct {
 			Platform *bool
 		}
+		Header_libs []string
+		Shared_libs []string
 	}{}
 
 	ccProps.Name = proptools.StringPtr(m.CcModuleName())
@@ -130,6 +132,8 @@
 	ccProps.Device_specific = proptools.BoolPtr(deviceSpecific)
 	ccProps.Product_specific = proptools.BoolPtr(productSpecific)
 	ccProps.Sysprop.Platform = proptools.BoolPtr(owner == "Platform")
+	ccProps.Header_libs = []string{"libbase_headers"}
+	ccProps.Shared_libs = []string{"liblog"}
 
 	ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &m.commonProperties, &ccProps)
 }