Refactor module name to be dynamic.

The target //foo:baz and //bar:baz will both always share a module name of "baz", which is not allowed.

This lays the groundwork to allow custom module names via the
Target->module_name() method.

Bug: chromium:465206266
Change-Id: I1e8ecf135b48cc100e3fad75ce6876866a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/20500
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Matt Stark <msta@google.com>
diff --git a/docs/reference.md b/docs/reference.md
index 1b490c7..fd24565 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -571,6 +571,7 @@
   visibility
   walk_keys
   weak_frameworks
+  weak_libraries
 
   runtime_deps
       Compute all runtime deps for the given target. This is a computed list
@@ -1329,6 +1330,7 @@
       Restricts output to targets which refer to input files by a specific
       relation. Defaults to any relation. Can be provided multiple times to
       include multiple relations.
+    
 ```
 
 #### **Examples (target input)**
@@ -3478,7 +3480,7 @@
   Directories and names of GN labels are usually considered trustworthy.
 ```
 
-#### **Examples**
+#### **Examples**:
 
 ```
     string_hash("abc")  -->  "90015098"
@@ -4117,6 +4119,9 @@
     {{cflags_cc}}
     {{cflags_objc}}
     {{cflags_objcc}}
+    {{cc_module_name}}
+        The C++ module name for the current target, if one is being built.
+        This is used when compiling C++ modules.
     {{defines}}
     {{include_dirs}}
         Strings correspond that to the processed flags/defines/include
@@ -4133,7 +4138,6 @@
         modules referenced by the current target. The "_no_self" version doesn't
         include the module for the current target, and can be used to compile
         the pcm itself.
-
     {{source}}
         The relative path and name of the current input file.
         Example: "../../base/my_file.cc"
diff --git a/src/gn/c_substitution_type.cc b/src/gn/c_substitution_type.cc
index b5ca3cd..2c7c8ce 100644
--- a/src/gn/c_substitution_type.cc
+++ b/src/gn/c_substitution_type.cc
@@ -21,6 +21,7 @@
     &CSubstitutionIncludeDirs,
     &CSubstitutionModuleDeps,
     &CSubstitutionModuleDepsNoSelf,
+    &CSubstitutionModuleName,
     &CSubstitutionSwiftModules,
 
     &CSubstitutionLinkerInputs,
@@ -55,6 +56,8 @@
 const Substitution CSubstitutionModuleDeps = {"{{module_deps}}", "module_deps"};
 const Substitution CSubstitutionModuleDepsNoSelf = {"{{module_deps_no_self}}",
                                                     "module_deps_no_self"};
+const Substitution CSubstitutionModuleName = {"{{cc_module_name}}",
+                                              "cc_module_name"};
 
 // Valid for linker tools.
 const Substitution CSubstitutionLinkerInputs = {"{{inputs}}", "in"};
@@ -89,7 +92,8 @@
          type == &CSubstitutionFrameworkDirs ||
          type == &CSubstitutionIncludeDirs ||
          type == &CSubstitutionModuleDeps ||
-         type == &CSubstitutionModuleDepsNoSelf;
+         type == &CSubstitutionModuleDepsNoSelf ||
+         type == &CSubstitutionModuleName;
 }
 
 bool IsValidCompilerScriptArgsSubstitution(const Substitution* type) {
diff --git a/src/gn/c_substitution_type.h b/src/gn/c_substitution_type.h
index d0d1f8c..163be01 100644
--- a/src/gn/c_substitution_type.h
+++ b/src/gn/c_substitution_type.h
@@ -25,6 +25,7 @@
 extern const Substitution CSubstitutionIncludeDirs;
 extern const Substitution CSubstitutionModuleDeps;
 extern const Substitution CSubstitutionModuleDepsNoSelf;
+extern const Substitution CSubstitutionModuleName;
 
 // Valid for linker tools.
 extern const Substitution CSubstitutionLinkerInputs;
diff --git a/src/gn/function_toolchain.cc b/src/gn/function_toolchain.cc
index 794351b..2f9bf57 100644
--- a/src/gn/function_toolchain.cc
+++ b/src/gn/function_toolchain.cc
@@ -672,6 +672,9 @@
     {{cflags_cc}}
     {{cflags_objc}}
     {{cflags_objcc}}
+    {{cc_module_name}}
+        The C++ module name for the current target, if one is being built.
+        This is used when compiling C++ modules.
     {{defines}}
     {{include_dirs}}
         Strings correspond that to the processed flags/defines/include
diff --git a/src/gn/ninja_c_binary_target_writer.cc b/src/gn/ninja_c_binary_target_writer.cc
index 4d9d6e9..c864bc0 100644
--- a/src/gn/ninja_c_binary_target_writer.cc
+++ b/src/gn/ninja_c_binary_target_writer.cc
@@ -168,6 +168,8 @@
   WriteCCompilerVars(subst, /*indent=*/false,
                      /*respect_source_types_used=*/true);
 
+  WriteModuleNameSubstitution();
+
   if (!module_dep_info.empty()) {
     // TODO(scottmg): Currently clang modules only working for C++.
     if (target_->source_types_used().Get(SourceFile::SOURCE_CPP) ||
@@ -182,6 +184,17 @@
   WriteSharedVars(subst);
 }
 
+void NinjaCBinaryTargetWriter::WriteModuleNameSubstitution() {
+  if (target_->toolchain()->substitution_bits().used.count(
+          &CSubstitutionModuleName)) {
+    out_ << CSubstitutionModuleName.ninja_name << " = ";
+    EscapeOptions options;
+    options.mode = ESCAPE_NINJA_COMMAND;
+    EscapeStringToStream(out_, target_->module_name(), options);
+    out_ << std::endl;
+  }
+}
+
 void NinjaCBinaryTargetWriter::WriteModuleDepsSubstitution(
     const Substitution* substitution,
     const std::vector<ClangModuleDep>& module_dep_info,
diff --git a/src/gn/ninja_c_binary_target_writer.h b/src/gn/ninja_c_binary_target_writer.h
index 39e8320..3707f0e 100644
--- a/src/gn/ninja_c_binary_target_writer.h
+++ b/src/gn/ninja_c_binary_target_writer.h
@@ -34,6 +34,9 @@
       const std::vector<ClangModuleDep>& module_dep_info,
       bool include_self);
 
+  // Writes module_name substitution for clang modulemaps.
+  void WriteModuleNameSubstitution();
+
   // Writes build lines required for precompiled headers. Any generated
   // object files will be appended to the |object_files|. Any generated
   // non-object files (for instance, .gch files from a GCC toolchain, are
diff --git a/src/gn/ninja_c_binary_target_writer_unittest.cc b/src/gn/ninja_c_binary_target_writer_unittest.cc
index 97ddad0..2072142 100644
--- a/src/gn/ninja_c_binary_target_writer_unittest.cc
+++ b/src/gn/ninja_c_binary_target_writer_unittest.cc
@@ -2532,7 +2532,7 @@
       Tool::CreateTool(CTool::kCToolCxxModule);
   TestWithScope::SetCommandForTool(
       "c++ {{source}} {{cflags}} {{cflags_cc}} {{module_deps_no_self}} "
-      "{{defines}} {{include_dirs}} -fmodule-name={{label}} -c -x c++ "
+      "{{defines}} {{include_dirs}} -fmodule-name={{cc_module_name}} -c -x c++ "
       "-Xclang -emit-module -o {{output}}",
       cxx_module_tool.get());
   cxx_module_tool->set_outputs(SubstitutionList::MakeForTest(
@@ -2584,9 +2584,9 @@
 include_dirs =
 cflags =
 cflags_cc =
+cc_module_name = a
 module_deps = -fmodule-file=a=obj/blah/liba.a.pcm
 module_deps_no_self =
-label = //blah$:a
 root_out_dir = withmodules
 target_out_dir = obj/blah
 target_output_name = liba
@@ -2630,9 +2630,9 @@
 include_dirs =
 cflags =
 cflags_cc =
+cc_module_name = b
 module_deps = -fmodule-file=a=obj/blah/liba.a.pcm -fmodule-file=b=obj/stuff/libb.b.pcm
 module_deps_no_self = -fmodule-file=a=obj/blah/liba.a.pcm
-label = //stuff$:b
 root_out_dir = withmodules
 target_out_dir = obj/stuff
 target_output_name = libb
@@ -2674,9 +2674,9 @@
 include_dirs =
 cflags =
 cflags_cc =
+cc_module_name = c
 module_deps = -fmodule-file=a=obj/blah/liba.a.pcm -fmodule-file=b=obj/stuff/libb.b.pcm -fmodule-file=c=obj/stuff/libc.c.pcm
 module_deps_no_self = -fmodule-file=a=obj/blah/liba.a.pcm -fmodule-file=b=obj/stuff/libb.b.pcm
-label = //things$:c
 root_out_dir = withmodules
 target_out_dir = obj/things
 target_output_name = libc
@@ -2714,9 +2714,9 @@
 include_dirs =
 cflags =
 cflags_cc =
+cc_module_name = c
 module_deps = -fmodule-file=a=obj/blah/liba.a.pcm -fmodule-file=b=obj/stuff/libb.b.pcm
 module_deps_no_self = -fmodule-file=a=obj/blah/liba.a.pcm -fmodule-file=b=obj/stuff/libb.b.pcm
-label = //zap$:c
 root_out_dir = withmodules
 target_out_dir = obj/zap
 target_output_name = c
diff --git a/src/gn/ninja_module_writer_util.cc b/src/gn/ninja_module_writer_util.cc
index 168895f..67b40eb 100644
--- a/src/gn/ninja_module_writer_util.cc
+++ b/src/gn/ninja_module_writer_util.cc
@@ -55,7 +55,7 @@
 
     if (added_pcms.insert(pcm_file).second) {
       // GN sets the module name to the name of the target.
-      ret.emplace_back(modulemap, t->label().name(), pcm_file, is_self);
+      ret.emplace_back(modulemap, t->module_name(), pcm_file, is_self);
     }
   };
 
diff --git a/src/gn/ninja_module_writer_util.h b/src/gn/ninja_module_writer_util.h
index 19a6444..f6d007b 100644
--- a/src/gn/ninja_module_writer_util.h
+++ b/src/gn/ninja_module_writer_util.h
@@ -23,7 +23,7 @@
   // The input module.modulemap source file.
   const SourceFile* modulemap;
 
-  // The internal module name, in GN this is the target's label.
+  // The internal module name.
   std::string module_name;
 
   // The compiled version of the module.
diff --git a/src/gn/target.h b/src/gn/target.h
index 4b0bed9..63a52ee 100644
--- a/src/gn/target.h
+++ b/src/gn/target.h
@@ -410,6 +410,9 @@
     return runtime_outputs_;
   }
 
+  // The module name for the target.
+  std::string module_name() const { return label().name(); }
+
   // Computes and returns the outputs of this target expressed as SourceFiles.
   //
   // For binary target this depends on the tool for this target so the toolchain