From 99839d115812a8ad87329e569db32415520c6e1c Mon Sep 17 00:00:00 2001 From: Eduard Voronkin Date: Fri, 12 Sep 2025 17:28:38 -0700 Subject: [PATCH] FASTBuild: expose more options Expose more options for compiler configuration as well as adding unit test --- Help/generator/FASTBuild.rst | 19 ++- Help/manual/cmake-variables.7.rst | 7 + .../CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst | 7 + ...E_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst | 7 + ...CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst | 7 + .../CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst | 7 + .../CMAKE_FASTBUILD_SOURCE_MAPPING.rst | 13 ++ ...MAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst | 7 + .../CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst | 7 + Source/cmGlobalFastbuildGenerator.cxx | 123 ++++++++++++++---- Source/cmGlobalFastbuildGenerator.h | 8 ++ Tests/RunCMake/FASTBuild/RunCMakeTest.cmake | 1 + .../FASTBuild/SetCompilerProps-check.cmake | 12 ++ .../RunCMake/FASTBuild/SetCompilerProps.cmake | 10 ++ 14 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst create mode 100644 Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst create mode 100644 Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst create mode 100644 Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst create mode 100644 Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst create mode 100644 Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst create mode 100644 Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst create mode 100644 Tests/RunCMake/FASTBuild/SetCompilerProps-check.cmake create mode 100644 Tests/RunCMake/FASTBuild/SetCompilerProps.cmake diff --git a/Help/generator/FASTBuild.rst b/Help/generator/FASTBuild.rst index 4c1936824e..8d5c46e41a 100644 --- a/Help/generator/FASTBuild.rst +++ b/Help/generator/FASTBuild.rst @@ -40,6 +40,23 @@ Then build with the ``-cache`` flag: cmake --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 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 989246e956..16893a1056 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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 diff --git a/Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst b/Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst new file mode 100644 index 0000000000..e385cefb8c --- /dev/null +++ b/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 `_ +for more information. diff --git a/Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst b/Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst new file mode 100644 index 0000000000..131960a130 --- /dev/null +++ b/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 `_ +for more information. diff --git a/Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst b/Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst new file mode 100644 index 0000000000..1ebf13fc80 --- /dev/null +++ b/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 `_ +for more information. diff --git a/Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst b/Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst new file mode 100644 index 0000000000..8155eacc82 --- /dev/null +++ b/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 `_ +for more information. diff --git a/Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst b/Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst new file mode 100644 index 0000000000..8411b1525a --- /dev/null +++ b/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 `_ +for more information. diff --git a/Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst b/Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst new file mode 100644 index 0000000000..87d0e87f6e --- /dev/null +++ b/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 `_ +for more information. diff --git a/Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst b/Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst new file mode 100644 index 0000000000..e701c5a362 --- /dev/null +++ b/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 `_ +for more information. diff --git a/Source/cmGlobalFastbuildGenerator.cxx b/Source/cmGlobalFastbuildGenerator.cxx index a0eaaed8da..c675e7d3c4 100644 --- a/Source/cmGlobalFastbuildGenerator.cxx +++ b/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 const compilerIdToFastbuildFamily = { + { "MSVC", "msvc" }, { "Clang", "clang" }, { "AppleClang", "clang" }, + { "GNU", "gcc" }, { "NVIDIA", "cuda-nvcc" }, { "Clang-cl", "clang-cl" }, +}; + +static std::set 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 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 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) diff --git a/Source/cmGlobalFastbuildGenerator.h b/Source/cmGlobalFastbuildGenerator.h index e8c47a2f32..89c12f61f2 100644 --- a/Source/cmGlobalFastbuildGenerator.h +++ b/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 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; diff --git a/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake b/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake index a4eaebe318..9784930246 100644 --- a/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake @@ -2,3 +2,4 @@ include(RunCMake) run_cmake(DisableCaching) run_cmake(DisableDistribution) +run_cmake(SetCompilerProps) diff --git a/Tests/RunCMake/FASTBuild/SetCompilerProps-check.cmake b/Tests/RunCMake/FASTBuild/SetCompilerProps-check.cmake new file mode 100644 index 0000000000..d91e3640ae --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/FASTBuild/SetCompilerProps.cmake b/Tests/RunCMake/FASTBuild/SetCompilerProps.cmake new file mode 100644 index 0000000000..1e59ac7fa3 --- /dev/null +++ b/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)