Przeglądaj źródła

FASTBuild: expose more options

Expose more options for compiler configuration as well as adding unit test
Eduard Voronkin 1 miesiąc temu
rodzic
commit
99839d1158

+ 17 - 2
Help/generator/FASTBuild.rst

@@ -40,6 +40,23 @@ Then build with the ``-cache`` flag:
 
    cmake --build <path-to-build> -- -cache
 
+Compiler Behavior Variables
+---------------------------
+
+The following variables control how compiler nodes are emitted in the generated
+``fbuild.bff``. These settings may affect build determinism, debug info paths,
+include handling, and compiler argument formatting:
+
+* :variable:`CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE`
+* :variable:`CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG`
+* :variable:`CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES`
+* :variable:`CMAKE_FASTBUILD_COMPILER_EXTRA_FILES`
+* :variable:`CMAKE_FASTBUILD_FORCE_RESPONSE_FILE`
+* :variable:`CMAKE_FASTBUILD_SOURCE_MAPPING`
+* :variable:`CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS`
+* :variable:`CMAKE_FASTBUILD_USE_LIGHTCACHE`
+* :variable:`CMAKE_FASTBUILD_USE_RELATIVE_PATHS`
+
 Configuration Variables
 -----------------------
 
@@ -47,10 +64,8 @@ The following variables can be used to configure this generator:
 
 * :variable:`CMAKE_FASTBUILD_CACHE_PATH`
 * :variable:`CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV`
-* :variable:`CMAKE_FASTBUILD_COMPILER_EXTRA_FILES`
 * :variable:`CMAKE_FASTBUILD_ENV_OVERRIDES`
 * :variable:`CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT`
-* :variable:`CMAKE_FASTBUILD_USE_LIGHTCACHE`
 * :variable:`CMAKE_FASTBUILD_VERBOSE_GENERATOR`
 
 Target Properties

+ 7 - 0
Help/manual/cmake-variables.7.rst

@@ -61,7 +61,14 @@ Variables that Provide Information
    /variable/CMAKE_FASTBUILD_COMPILER_EXTRA_FILES
    /variable/CMAKE_FASTBUILD_ENV_OVERRIDES
    /variable/CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT
+   /variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE
+   /variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG
+   /variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES
+   /variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE
+   /variable/CMAKE_FASTBUILD_SOURCE_MAPPING
+   /variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS
    /variable/CMAKE_FASTBUILD_USE_LIGHTCACHE
+   /variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS
    /variable/CMAKE_FASTBUILD_VERBOSE_GENERATOR
    /variable/CMAKE_FIND_DEBUG_MODE
    /variable/CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG

+ 7 - 0
Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst

@@ -0,0 +1,7 @@
+CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE
+-----------------------------------
+
+Enables FASTBuild's ``AllowResponseFile`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 7 - 0
Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst

@@ -0,0 +1,7 @@
+CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG
+------------------------------------------
+
+Enables FASTBuild's ``ClangGCCUpdateXLanguageArg`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 7 - 0
Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst

@@ -0,0 +1,7 @@
+CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES
+--------------------------------------
+
+Enables FASTBuild's ``ClangRewriteIncludes`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 7 - 0
Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst

@@ -0,0 +1,7 @@
+CMAKE_FASTBUILD_FORCE_RESPONSE_FILE
+-----------------------------------
+
+Enables FASTBuild's ``ForceResponseFile`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 13 - 0
Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst

@@ -0,0 +1,13 @@
+CMAKE_FASTBUILD_SOURCE_MAPPING
+------------------------------
+
+Sets FASTBuild's ``SourceMapping_Experimental`` option.
+
+Example:
+
+.. code-block:: cmake
+
+   set(CMAKE_FASTBUILD_SOURCE_MAPPING "/another/root")
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 7 - 0
Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst

@@ -0,0 +1,7 @@
+CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS
+---------------------------------------
+
+Enables FASTBuild's ``UseDeterministicPaths_Experimental`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 7 - 0
Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst

@@ -0,0 +1,7 @@
+CMAKE_FASTBUILD_USE_RELATIVE_PATHS
+----------------------------------
+
+Enables FASTBuild's ``UseRelativePaths_Experimental`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.

+ 100 - 23
Source/cmGlobalFastbuildGenerator.cxx

@@ -69,6 +69,62 @@ constexpr auto FASTBUILD_CACHE_PATH = "CMAKE_FASTBUILD_CACHE_PATH";
 constexpr auto FASTBUILD_COMPILER_EXTRA_FILES =
   "CMAKE_FASTBUILD_COMPILER_EXTRA_FILES";
 constexpr auto FASTBUILD_USE_LIGHTCACHE = "CMAKE_FASTBUILD_USE_LIGHTCACHE";
+constexpr auto FASTBUILD_USE_RELATIVE_PATHS =
+  "CMAKE_FASTBUILD_USE_RELATIVE_PATHS";
+constexpr auto FASTBUILD_USE_DETERMINISTIC_PATHS =
+  "CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS";
+constexpr auto FASTBUILD_SOURCE_MAPPING = "CMAKE_FASTBUILD_SOURCE_MAPPING";
+constexpr auto FASTBUILD_CLANG_REWRITE_INCLUDES =
+  "CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES";
+constexpr auto FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG =
+  "CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG";
+constexpr auto FASTBUILD_ALLOW_RESPONSE_FILE =
+  "CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE";
+constexpr auto FASTBUILD_FORCE_RESPONSE_FILE =
+  "CMAKE_FASTBUILD_FORCE_RESPONSE_FILE";
+
+static std::map<std::string, std::string> const compilerIdToFastbuildFamily = {
+  { "MSVC", "msvc" }, { "Clang", "clang" },      { "AppleClang", "clang" },
+  { "GNU", "gcc" },   { "NVIDIA", "cuda-nvcc" }, { "Clang-cl", "clang-cl" },
+};
+
+static std::set<std::string> const supportedLanguages = { "C", "CXX", "CUDA",
+                                                          "OBJC", "OBJCXX" };
+
+static void ReadCompilerOptions(FastbuildCompiler& compiler, cmMakefile* mf)
+{
+  if (compiler.CompilerFamily == "custom") {
+    return;
+  }
+
+  if (cmIsOn(mf->GetSafeDefinition(FASTBUILD_USE_LIGHTCACHE))) {
+    compiler.UseLightCache = true;
+  }
+  if (cmIsOn(mf->GetSafeDefinition(FASTBUILD_USE_RELATIVE_PATHS))) {
+    compiler.UseRelativePaths = true;
+  }
+  if (cmIsOn(mf->GetSafeDefinition(FASTBUILD_USE_DETERMINISTIC_PATHS))) {
+    compiler.UseDeterministicPaths = true;
+  }
+  std::string sourceMapping = mf->GetSafeDefinition(FASTBUILD_SOURCE_MAPPING);
+  if (!sourceMapping.empty()) {
+    compiler.SourceMapping = std::move(sourceMapping);
+  }
+  auto const clangRewriteIncludesDef =
+    mf->GetDefinition(FASTBUILD_CLANG_REWRITE_INCLUDES);
+  if (clangRewriteIncludesDef.IsSet() && clangRewriteIncludesDef.IsOff()) {
+    compiler.ClangRewriteIncludes = false;
+  }
+  if (cmIsOn(mf->GetSafeDefinition(FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG))) {
+    compiler.ClangGCCUpdateXLanguageArg = true;
+  }
+  if (cmIsOn(mf->GetSafeDefinition(FASTBUILD_ALLOW_RESPONSE_FILE))) {
+    compiler.AllowResponseFile = true;
+  }
+  if (cmIsOn(mf->GetSafeDefinition(FASTBUILD_FORCE_RESPONSE_FILE))) {
+    compiler.ForceResponseFile = true;
+  }
+}
 
 template <class T>
 FastbuildAliasNode generateAlias(std::string const& name, char const* postfix,
@@ -815,21 +871,6 @@ void cmGlobalFastbuildGenerator::WriteCompilers()
   for (auto const& val : Compilers) {
     auto const& compilerDef = val.second;
 
-    std::string fastbuildFamily = "custom";
-
-    if (compilerDef.Language == "C" || compilerDef.Language == "CXX" ||
-        compilerDef.Language == "CUDA") {
-      std::map<std::string, std::string> compilerIdToFastbuildFamily = {
-        { "MSVC", "msvc" },        { "Clang", "clang" },
-        { "AppleClang", "clang" }, { "GNU", "gcc" },
-        { "NVIDIA", "cuda-nvcc" }, { "Clang-cl", "clang-cl" },
-      };
-      auto ft = compilerIdToFastbuildFamily.find(compilerDef.CmakeCompilerID);
-      if (ft != compilerIdToFastbuildFamily.end()) {
-        fastbuildFamily = ft->second;
-      }
-    }
-
     std::string compilerPath = compilerDef.Executable;
 
     // Write out the compiler that has been configured
@@ -841,13 +882,43 @@ void cmGlobalFastbuildGenerator::WriteCompilers()
       WriteVariable(extraKey, Quote(extraVal), 1);
     }
     WriteVariable("Executable", Quote(compilerPath), 1);
-    WriteVariable("CompilerFamily", Quote(fastbuildFamily), 1);
-    if (compilerDef.UseLightCache) {
+    WriteVariable("CompilerFamily", Quote(compilerDef.CompilerFamily), 1);
+
+    if (compilerDef.UseLightCache && compilerDef.CompilerFamily == "msvc") {
       WriteVariable("UseLightCache_Experimental", "true", 1);
     }
-    if (fastbuildFamily == "clang") {
+    if (compilerDef.UseRelativePaths) {
+      WriteVariable("UseRelativePaths_Experimental", "true", 1);
+    }
+    if (compilerDef.UseDeterministicPaths) {
+      WriteVariable("UseDeterministicPaths_Experimental", "true", 1);
+    }
+
+    if (!compilerDef.SourceMapping.empty()) {
+      WriteVariable("SourceMapping_Experimental",
+                    Quote(compilerDef.SourceMapping), 1);
+    }
+
+    auto const isClang = [&compilerDef] {
+      return compilerDef.CompilerFamily == "clang" ||
+        compilerDef.CompilerFamily == "clang-cl";
+    };
+
+    if (!compilerDef.ClangRewriteIncludes && isClang()) {
       WriteVariable("ClangRewriteIncludes", "false", 1);
     }
+    if (compilerDef.ClangGCCUpdateXLanguageArg &&
+        (isClang() || compilerDef.CompilerFamily == "gcc")) {
+      WriteVariable("ClangGCCUpdateXLanguageArg", "true", 1);
+    }
+
+    if (compilerDef.AllowResponseFile) {
+      WriteVariable("AllowResponseFile", "true", 1);
+    }
+    if (compilerDef.ForceResponseFile) {
+
+      WriteVariable("ForceResponseFile", "true", 1);
+    }
 
     if (compilerDef.DontUseEnv) {
       LogMessage("Not using system environment");
@@ -913,14 +984,20 @@ void cmGlobalFastbuildGenerator::AddCompiler(std::string const& language,
     mf->GetSafeDefinition("CMAKE_" + language + "_COMPILER_VERSION");
   compilerDef.Language = language;
 
-  if (compilerDef.CmakeCompilerID == "MSVC" &&
-      cmIsOn(mf->GetSafeDefinition(FASTBUILD_USE_LIGHTCACHE)) &&
-      (language == "C" || language == "CXX")) {
-    compilerDef.UseLightCache = true;
-  }
   cmExpandList(mf->GetSafeDefinition(FASTBUILD_COMPILER_EXTRA_FILES),
                compilerDef.ExtraFiles);
 
+  if (supportedLanguages.find(language) != supportedLanguages.end()) {
+    auto const iter =
+      compilerIdToFastbuildFamily.find(compilerDef.CmakeCompilerID);
+    if (iter != compilerIdToFastbuildFamily.end()) {
+      compilerDef.CompilerFamily = iter->second;
+    }
+  }
+
+  // Has to be called after we determined 'CompilerFamily'.
+  ReadCompilerOptions(compilerDef, mf);
+
   // If FASTBUILD_COMPILER_EXTRA_FILES is not set - automatically add extra
   // files based on compiler (see
   // https://fastbuild.org/docs/functions/compiler.html)

+ 8 - 0
Source/cmGlobalFastbuildGenerator.h

@@ -186,10 +186,18 @@ struct FastbuildCompiler
   std::string Name;
   std::string Executable;
   std::string CmakeCompilerID;
+  std::string CompilerFamily = "custom";
   std::string CmakeCompilerVersion;
   std::string Language;
   std::vector<std::string> ExtraFiles;
   bool UseLightCache = false;
+  bool ClangRewriteIncludes = true;
+  bool ClangGCCUpdateXLanguageArg = false;
+  bool AllowResponseFile = false;
+  bool ForceResponseFile = false;
+  bool UseRelativePaths = false;
+  bool UseDeterministicPaths = false;
+  std::string SourceMapping;
   // Only used for launchers.
   std::string Args;
   bool DontUseEnv = false;

+ 1 - 0
Tests/RunCMake/FASTBuild/RunCMakeTest.cmake

@@ -2,3 +2,4 @@ include(RunCMake)
 
 run_cmake(DisableCaching)
 run_cmake(DisableDistribution)
+run_cmake(SetCompilerProps)

+ 12 - 0
Tests/RunCMake/FASTBuild/SetCompilerProps-check.cmake

@@ -0,0 +1,12 @@
+set(REGEX_TO_MATCH "
+.*.UseRelativePaths_Experimental = true.*
+.*.UseDeterministicPaths_Experimental = true.*
+.*.SourceMapping_Experimental = '/new/root'.*
+.*.AllowResponseFile = true.*
+.*.ExtraFiles =.*
+.*{
+.*'file1',
+.*'file2'
+.*}
+")
+include(${RunCMake_SOURCE_DIR}/check.cmake)

+ 10 - 0
Tests/RunCMake/FASTBuild/SetCompilerProps.cmake

@@ -0,0 +1,10 @@
+# Generic
+set(CMAKE_FASTBUILD_USE_RELATIVE_PATHS ON)
+set(CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS ON)
+set(CMAKE_FASTBUILD_SOURCE_MAPPING "/new/root")
+set(CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE ON)
+# This should not appear in the generated file, since it's a default value.
+set(CMAKE_FASTBUILD_FORCE_RESPONSE_FILE OFF)
+set(CMAKE_FASTBUILD_COMPILER_EXTRA_FILES "file1;file2")
+
+add_executable(main main.cpp)