From 851e07fda3acac099451f4e4a6b44da70dc26546 Mon Sep 17 00:00:00 2001 From: John Parent Date: Wed, 21 May 2025 23:11:31 +0200 Subject: [PATCH] Ninja: support short object directories --- Help/release/dev/short-object-names.rst | 5 +++- Source/cmGlobalNinjaGenerator.cxx | 7 ++++- Source/cmGlobalNinjaGenerator.h | 1 + Source/cmLocalNinjaGenerator.cxx | 9 ++++++ Source/cmLocalNinjaGenerator.h | 1 + Source/cmNinjaTargetGenerator.cxx | 6 ++++ Tests/RunCMake/Ninja/LooseObjectDepends.cmake | 2 ++ .../Ninja/LooseObjectDependsShort.cmake | 27 +++++++++++++++++ Tests/RunCMake/Ninja/RunCMakeTest.cmake | 29 +++++++++++++++++++ .../Ninja/StaticLibShort-build-stdout.txt | 1 + Tests/RunCMake/Ninja/StaticLibShort.cmake | 7 +++++ Tests/RunCMake/Ninja/VerboseBuild.cmake | 2 ++ .../Ninja/VerboseBuildShort-build-stdout.txt | 1 + .../Ninja/VerboseBuildShort-nowork-stdout.txt | 1 + Tests/RunCMake/Ninja/VerboseBuildShort.cmake | 5 ++++ .../NinjaMultiConfig/CompileCommands.cmake | 2 ++ .../CustomCommandOutputGenex.cmake | 2 ++ .../CustomCommandsAndTargets.cmake | 2 ++ .../NinjaMultiConfig/ExcludeFromAll.cmake | 2 ++ .../NinjaMultiConfig/PostfixAndLocation.cmake | 2 ++ .../NinjaPrivateDeps/CMP0154-common.cmake | 2 ++ .../RunCMake/ObjectLibrary/RunCMakeTest.cmake | 2 +- .../PrecompileHeaders/RunCMakeTest.cmake | 2 +- Tests/RunCMake/UnityBuild/RunCMakeTest.cmake | 2 +- 24 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 Tests/RunCMake/Ninja/LooseObjectDependsShort.cmake create mode 100644 Tests/RunCMake/Ninja/StaticLibShort-build-stdout.txt create mode 100644 Tests/RunCMake/Ninja/StaticLibShort.cmake create mode 100644 Tests/RunCMake/Ninja/VerboseBuildShort-build-stdout.txt create mode 100644 Tests/RunCMake/Ninja/VerboseBuildShort-nowork-stdout.txt create mode 100644 Tests/RunCMake/Ninja/VerboseBuildShort.cmake diff --git a/Help/release/dev/short-object-names.rst b/Help/release/dev/short-object-names.rst index 1ae306d190..1bed98b2fe 100644 --- a/Help/release/dev/short-object-names.rst +++ b/Help/release/dev/short-object-names.rst @@ -4,4 +4,7 @@ short-object-names * There is now the :variable:`CMAKE_INTERMEDIATE_DIR_STRATEGY` variable (and associated environment variable :envvar:`CMAKE_INTERMEDIATE_DIR_STRATEGY`) that may be used to change the strategy used to name intermediate - directories used for object files (and other associated target metadata). + directories used for object files (and other associated target metadata). It + is supported for the following generators: + + - :ref:`Ninja Generators` diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index b886885008..7a2c36ad47 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1048,6 +1048,11 @@ bool cmGlobalNinjaGenerator::HasRule(std::string const& name) // Private virtual overrides +bool cmGlobalNinjaGenerator::SupportsShortObjectNames() const +{ + return true; +} + void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { @@ -2276,7 +2281,7 @@ void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix( /* We use the following approach to support Fortran. Each target already -has a .dir/ directory used to hold intermediate files for CMake. +has an intermediate directory used to hold intermediate files for CMake. For each target, a FortranDependInfo.json file is generated by CMake with information about include directories, module directories, and the locations the per-target directories for target dependencies. diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index c27437b127..6fac392c68 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -391,6 +391,7 @@ public: void AddTargetAlias(std::string const& alias, cmGeneratorTarget* target, std::string const& config); + bool SupportsShortObjectNames() const override; void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override; // Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3 diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index b0c4051b64..23b2ef23d5 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -163,6 +163,15 @@ void cmLocalNinjaGenerator::Generate() } } +std::string cmLocalNinjaGenerator::GetObjectOutputRoot() const +{ + if (this->UseShortObjectNames()) { + return cmStrCat(this->GetBinaryDirectory(), '/', + this->GetGlobalGenerator()->GetShortBinaryOutputDir()); + } + return cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles"); +} + // Non-virtual public methods. cmGlobalNinjaGenerator const* cmLocalNinjaGenerator::GetGlobalNinjaGenerator() diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 95f5c8909a..aa08710e25 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -62,6 +62,7 @@ public: { return this->HomeRelativeOutputPath; } + std::string GetObjectOutputRoot() const override; std::string BuildCommandLine( std::vector const& cmdLines, std::string const& outputConfig, diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 11ff6a7cfc..25f6d36359 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -1414,6 +1414,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( vars["DEFINES"] = this->ComputeDefines(source, language, config); vars["INCLUDES"] = this->ComputeIncludes(source, language, config); vars["CONFIG"] = config; + if (this->GetGeneratorTarget()->GetUseShortObjectNames()) { + vars.emplace( + "description", + cmStrCat("Compiling object ", objectFileName, " from source ", + this->GetLocalGenerator()->GetRelativeSourceFileName(*source))); + } auto compilerLauncher = this->GetCompilerLauncher(language, config); diff --git a/Tests/RunCMake/Ninja/LooseObjectDepends.cmake b/Tests/RunCMake/Ninja/LooseObjectDepends.cmake index 90f824978a..83911e1877 100644 --- a/Tests/RunCMake/Ninja/LooseObjectDepends.cmake +++ b/Tests/RunCMake/Ninja/LooseObjectDepends.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) add_custom_command( diff --git a/Tests/RunCMake/Ninja/LooseObjectDependsShort.cmake b/Tests/RunCMake/Ninja/LooseObjectDependsShort.cmake new file mode 100644 index 0000000000..21252dc790 --- /dev/null +++ b/Tests/RunCMake/Ninja/LooseObjectDependsShort.cmake @@ -0,0 +1,27 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +enable_language(C) + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/command.h" + COMMAND "${CMAKE_COMMAND}" -E touch + "${CMAKE_CURRENT_BINARY_DIR}/command.h" + COMMENT "Creating command.h") +add_custom_target(create-command.h + DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/command.h") + +add_custom_target(create-target.h + BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/target.h" + COMMAND "${CMAKE_COMMAND}" -E touch + "${CMAKE_CURRENT_BINARY_DIR}/target.h" + COMMENT "Creating target.h") + +add_library(dep SHARED dep.c) +add_dependencies(dep create-command.h create-target.h) +target_include_directories(dep + PUBLIC + "${CMAKE_CURRENT_BINARY_DIR}") + +add_library(top top.c) +target_link_libraries(top PRIVATE dep) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index ca360f75c7..81606cbb60 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -83,6 +83,16 @@ function(run_VerboseBuild) endfunction() run_VerboseBuild() +function(run_VerboseBuildShort) + run_cmake(VerboseBuildShort) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VerboseBuildShort-build) + set(RunCMake_TEST_OUTPUT_MERGE 1) + run_cmake_command(VerboseBuildShort-build ${CMAKE_COMMAND} --build . -v --clean-first) + run_cmake_command(VerboseBuildShort-nowork ${CMAKE_COMMAND} --build . --verbose) +endfunction() +run_VerboseBuildShort() + function(run_CMP0058 case) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0058-${case}-build) @@ -195,6 +205,23 @@ function (run_LooseObjectDepends) endfunction () run_LooseObjectDepends() +function (run_LooseObjectDependsShort) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LooseObjectDependsShort-build) + run_cmake(LooseObjectDependsShort) + run_ninja("${RunCMake_TEST_BINARY_DIR}" ".o/e86fd702/b1363cd8${CMAKE_C_OUTPUT_EXTENSION}") + if (EXISTS "${RunCMake_TEST_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}dep${CMAKE_SHARED_LIBRARY_SUFFIX}") + message(FATAL_ERROR + "The `dep` library was created when requesting an object file to be " + "built; this should no longer be necessary.") + endif () + if (EXISTS "${RunCMake_TEST_BINARY_DIR}/.o/600bd702/d56215${CMAKE_C_OUTPUT_EXTENSION}") + message(FATAL_ERROR + "The `dep.c` object file was created when requesting an object file to " + "be built; this should no longer be necessary.") + endif () +endfunction () +run_LooseObjectDependsShort() + function (run_CustomCommandExplictDepends) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandExplicitDepends-build) run_cmake(CustomCommandExplicitDepends) @@ -425,3 +452,5 @@ if(CMake_TEST_Qt_version) endif() run_cmake(LINK_OPTIONSWithNewlines) + +run_cmake(StaticLibShort) diff --git a/Tests/RunCMake/Ninja/StaticLibShort-build-stdout.txt b/Tests/RunCMake/Ninja/StaticLibShort-build-stdout.txt new file mode 100644 index 0000000000..da52e4ec81 --- /dev/null +++ b/Tests/RunCMake/Ninja/StaticLibShort-build-stdout.txt @@ -0,0 +1 @@ +.*.o.75d5d702.cf59cf\.o.* diff --git a/Tests/RunCMake/Ninja/StaticLibShort.cmake b/Tests/RunCMake/Ninja/StaticLibShort.cmake new file mode 100644 index 0000000000..4b9a09444d --- /dev/null +++ b/Tests/RunCMake/Ninja/StaticLibShort.cmake @@ -0,0 +1,7 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +enable_language(C) +add_library(greeting STATIC greeting.c) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +add_executable(hello hello_with_greeting.c) +target_link_libraries(hello greeting) diff --git a/Tests/RunCMake/Ninja/VerboseBuild.cmake b/Tests/RunCMake/Ninja/VerboseBuild.cmake index 424e54eece..cc3d9d05f9 100644 --- a/Tests/RunCMake/Ninja/VerboseBuild.cmake +++ b/Tests/RunCMake/Ninja/VerboseBuild.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) add_executable(hello hello.c) target_compile_definitions(hello PRIVATE "DEFINE_FOR_VERBOSE_DETECTION") diff --git a/Tests/RunCMake/Ninja/VerboseBuildShort-build-stdout.txt b/Tests/RunCMake/Ninja/VerboseBuildShort-build-stdout.txt new file mode 100644 index 0000000000..5fd67d6fad --- /dev/null +++ b/Tests/RunCMake/Ninja/VerboseBuildShort-build-stdout.txt @@ -0,0 +1 @@ +DEFINE_FOR_VERBOSE_DETECTION.*75d5d702.4efa03e1.o diff --git a/Tests/RunCMake/Ninja/VerboseBuildShort-nowork-stdout.txt b/Tests/RunCMake/Ninja/VerboseBuildShort-nowork-stdout.txt new file mode 100644 index 0000000000..40b4527f7e --- /dev/null +++ b/Tests/RunCMake/Ninja/VerboseBuildShort-nowork-stdout.txt @@ -0,0 +1 @@ +ninja: no work to do diff --git a/Tests/RunCMake/Ninja/VerboseBuildShort.cmake b/Tests/RunCMake/Ninja/VerboseBuildShort.cmake new file mode 100644 index 0000000000..914d01e399 --- /dev/null +++ b/Tests/RunCMake/Ninja/VerboseBuildShort.cmake @@ -0,0 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +enable_language(C) +add_executable(hello hello.c) +target_compile_definitions(hello PRIVATE "DEFINE_FOR_VERBOSE_DETECTION") diff --git a/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake b/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake index fc44d5ad84..eeb3c9acc1 100644 --- a/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) add_executable(exe main.c) diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake index 2de5a3a777..ab3e7cff0e 100644 --- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandOutputGenex.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) add_executable(echo echo.c) diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake index b7e4aeab20..00feb9e645 100644 --- a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) file(REMOVE "${CMAKE_BINARY_DIR}/target_files_custom.cmake") diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake index 52f84ea920..46d8aad89e 100644 --- a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "") diff --git a/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake index abef3c881c..d0b1180e12 100644 --- a/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(C) set(CMAKE_DEBUG_POSTFIX "_debug") diff --git a/Tests/RunCMake/NinjaPrivateDeps/CMP0154-common.cmake b/Tests/RunCMake/NinjaPrivateDeps/CMP0154-common.cmake index a9e6d20e7a..8819f32882 100644 --- a/Tests/RunCMake/NinjaPrivateDeps/CMP0154-common.cmake +++ b/Tests/RunCMake/NinjaPrivateDeps/CMP0154-common.cmake @@ -1,3 +1,5 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + enable_language(CXX) function(copy_file file dest) diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake index 95c3920a1a..8e74f5c3e2 100644 --- a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake +++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake @@ -91,6 +91,6 @@ function(run_Dependencies suffix) endfunction() run_Dependencies("") -if (CMAKE_GENERATOR MATCHES "NONE") +if (CMAKE_GENERATOR MATCHES "Ninja") run_Dependencies(Short) endif () diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index 6637e74f13..b837f4c0b1 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -18,7 +18,7 @@ endfunction() run_cmake(DisabledPch) run_cmake(PchDebugGenex) run_test(PchInterface) -if (CMAKE_GENERATOR MATCHES "NONE") +if (CMAKE_GENERATOR MATCHES "Ninja") run_test(PchInterfaceShort) endif () run_test(PchInterfaceUnity) diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake index 25e0f4c9c2..b9e6765776 100644 --- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake @@ -72,6 +72,6 @@ endfunction() run_test(unitybuild_runtest) run_test(unitybuild_object_library) -if (CMAKE_GENERATOR MATCHES "NONE") +if (CMAKE_GENERATOR MATCHES "Ninja") run_build(unitybuild_cxx_short) endif ()