Rustdoc support.

Adds `m rustdoc` which generates documentation for all Rust libraries
to $OUT_DIR/soong/rustdoc.

Follow up work:

* Generate an index page that lists all modules.
* Preserve the artifacts so we can have an always-up-to-date go link.

Test: m rustdoc
Bug: None
Change-Id: Id2d6b9cbab5b02e36b575567563d7cc7606b9401
diff --git a/rust/library.go b/rust/library.go
index 26c104c..4e6031d 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -432,14 +432,10 @@
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	var outputFile android.ModuleOutPath
 	var fileName string
-	var srcPath android.Path
+	srcPath := library.srcPath(ctx, deps)
 
 	if library.sourceProvider != nil {
-		// Assume the first source from the source provider is the library entry point.
-		srcPath = library.sourceProvider.Srcs()[0]
 		deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
-	} else {
-		srcPath, _ = srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
 	}
 
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
@@ -457,22 +453,22 @@
 		fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+		TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile)
 	} else if library.dylib() {
 		fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+		TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile)
 	} else if library.static() {
 		fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+		TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile)
 	} else if library.shared() {
 		fileName = library.sharedLibFilename(ctx)
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+		TransformSrctoShared(ctx, srcPath, deps, flags, outputFile)
 	}
 
 	if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
@@ -513,6 +509,31 @@
 	return outputFile
 }
 
+func (library *libraryDecorator) srcPath(ctx ModuleContext, deps PathDeps) android.Path {
+	if library.sourceProvider != nil {
+		// Assume the first source from the source provider is the library entry point.
+		return library.sourceProvider.Srcs()[0]
+	} else {
+		path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
+		return path
+	}
+}
+
+func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
+	deps PathDeps) android.OptionalPath {
+	// rustdoc has builtin support for documenting config specific information
+	// regardless of the actual config it was given
+	// (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
+	// so we generate the rustdoc for only the primary module so that we have a
+	// single set of docs to refer to.
+	if ctx.Module() != ctx.PrimaryModule() {
+		return android.OptionalPath{}
+	}
+
+	return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
+		deps, flags))
+}
+
 func (library *libraryDecorator) getStem(ctx ModuleContext) string {
 	stem := library.baseCompiler.getStemWithoutSuffix(ctx)
 	validateLibraryStem(ctx, stem, library.crateName())