autogen: support the SHORT intermediate dir strategy

This commit is contained in:
Ben Boeckel
2025-07-29 09:44:03 -04:00
parent f97d1bf7d8
commit 8180ecad9b
46 changed files with 352 additions and 43 deletions
@@ -0,0 +1,10 @@
CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
---------------------------------------
.. versionadded:: 4.2
.. include:: include/ENV_VAR.rst
``CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY`` is a string specifying the
strategy to use for autogen-related target intermediate directories. It
initializes the :variable:`CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY` variable.
+1
View File
@@ -44,6 +44,7 @@ Environment Variables that Control the Build
/envvar/ADSP_ROOT
/envvar/CMAKE_APPLE_SILICON_PROCESSOR
/envvar/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
/envvar/CMAKE_BUILD_PARALLEL_LEVEL
/envvar/CMAKE_BUILD_TYPE
/envvar/CMAKE_COLOR_DIAGNOSTICS
+1
View File
@@ -191,6 +191,7 @@ Variables that Change Behavior
/variable/CMAKE_ABSOLUTE_DESTINATION_FILES
/variable/CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
/variable/CMAKE_APPBUNDLE_PATH
/variable/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
/variable/CMAKE_BUILD_TYPE
/variable/CMAKE_CLANG_VFS_OVERLAY
/variable/CMAKE_CODEBLOCKS_COMPILER_ID
+6
View File
@@ -12,3 +12,9 @@ short-object-names
- :ref:`Visual Studio Generators`
Note that the strategy implementation may differ between generators.
* There is now the :variable:`CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY`
variable (and associated environment variable
:envvar:`CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY`)
that may be used to change the strategy used to name intermediate
directories used for :manual:`Qt Autogen <cmake-qt(7)>` files.
@@ -0,0 +1,27 @@
CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
---------------------------------------
.. versionadded:: 4.2
``CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY`` is a string cache variable
specifying the strategy to use for autogen target intermediate directories and
their contents. The supported values are:
- ``FULL``: Intermediate directories are named based on a
``<TARGET_NAME>_autogen.dir`` and ``<TARGET_NAME>_autogen`` pattern (with
some slight deviations and sanitizations applied in various places). Object
file names are based on the filename of the source file being compiled.
- ``SHORT``: Intermediate directories are named from the hash of the target
name and the build directory location and an ``/autogen`` subdirectory.
This may help with projects that generate long paths in the build directory
to support building in directories other than those near a root path.
When unset or the named strategy is not supported, the ``FULL`` strategy is
used.
.. note::
This only works as a cache variable, not a locally-scoped variable.
.. note::
Not all generators support all strategies and paths may differ between
generators.
+10 -6
View File
@@ -45,6 +45,7 @@
#include "cmStandardLevel.h"
#include "cmStandardLevelResolver.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSyntheticTargetCache.h"
#include "cmSystemTools.h"
@@ -5363,26 +5364,29 @@ bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const
this->GetType() == cmStateEnums::MODULE_LIBRARY));
}
bool cmGeneratorTarget::GetUseShortObjectNames() const
bool cmGeneratorTarget::GetUseShortObjectNames(
cmStateEnums::IntermediateDirKind kind) const
{
return this->LocalGenerator->UseShortObjectNames();
return this->LocalGenerator->UseShortObjectNames(kind);
}
std::string cmGeneratorTarget::GetSupportDirectory() const
std::string cmGeneratorTarget::GetSupportDirectory(
cmStateEnums::IntermediateDirKind kind) const
{
cmLocalGenerator* lg = this->GetLocalGenerator();
return cmStrCat(lg->GetObjectOutputRoot(), '/',
return cmStrCat(lg->GetObjectOutputRoot(kind), '/',
lg->GetTargetDirectory(this));
}
std::string cmGeneratorTarget::GetCMFSupportDirectory() const
std::string cmGeneratorTarget::GetCMFSupportDirectory(
cmStateEnums::IntermediateDirKind kind) const
{
cmLocalGenerator* lg = this->GetLocalGenerator();
if (!lg->AlwaysUsesCMFPaths()) {
return cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
lg->GetTargetDirectory(this));
}
return cmStrCat(lg->GetObjectOutputRoot(), '/',
return cmStrCat(lg->GetObjectOutputRoot(kind), '/',
lg->GetTargetDirectory(this));
}
+9 -3
View File
@@ -937,11 +937,17 @@ public:
/** Return whether or not the target has a DLL import library. */
bool HasImportLibrary(std::string const& config) const;
bool GetUseShortObjectNames() const;
bool GetUseShortObjectNames(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const;
/** Get a build-tree directory in which to place target support files. */
std::string GetSupportDirectory() const;
std::string GetCMFSupportDirectory() const;
std::string GetSupportDirectory(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const;
std::string GetCMFSupportDirectory(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const;
/** Return whether this target may be used to link another target. */
bool IsLinkable() const;
+29 -2
View File
@@ -1453,6 +1453,20 @@ bool cmGlobalGenerator::Compute()
return false;
}
}
if (cmValue v = this->CMakeInstance->GetCacheDefinition(
"CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY")) {
if (*v == "FULL") {
this->QtAutogenIntDirStrategy = IntermediateDirStrategy::Full;
} else if (*v == "SHORT") {
this->QtAutogenIntDirStrategy = IntermediateDirStrategy::Short;
} else {
this->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Unsupported autogen intermediate directory strategy '", *v,
'\''));
return false;
}
}
// Some generators track files replaced during the Generate.
// Start with an empty vector:
@@ -2000,10 +2014,23 @@ bool cmGlobalGenerator::SupportsShortObjectNames() const
return false;
}
bool cmGlobalGenerator::UseShortObjectNames() const
bool cmGlobalGenerator::UseShortObjectNames(
cmStateEnums::IntermediateDirKind kind) const
{
IntermediateDirStrategy strategy = IntermediateDirStrategy::Full;
switch (kind) {
case cmStateEnums::IntermediateDirKind::ObjectFiles:
strategy = this->IntDirStrategy;
break;
case cmStateEnums::IntermediateDirKind::QtAutogenMetadata:
strategy = this->QtAutogenIntDirStrategy;
break;
default:
assert(false);
break;
}
return this->SupportsShortObjectNames() &&
this->IntDirStrategy == IntermediateDirStrategy::Short;
strategy == IntermediateDirStrategy::Short;
}
std::string cmGlobalGenerator::GetShortBinaryOutputDir() const
+5 -1
View File
@@ -630,7 +630,9 @@ public:
void AddCMP0068WarnTarget(std::string const& target);
virtual bool SupportsShortObjectNames() const;
bool UseShortObjectNames() const;
bool UseShortObjectNames(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const;
virtual std::string GetShortBinaryOutputDir() const;
std::string ComputeTargetShortName(std::string const& bindir,
std::string const& targetName) const;
@@ -953,6 +955,8 @@ private:
Short,
};
IntermediateDirStrategy IntDirStrategy = IntermediateDirStrategy::Full;
IntermediateDirStrategy QtAutogenIntDirStrategy =
IntermediateDirStrategy::Full;
protected:
float FirstTimeProgress;
+9 -3
View File
@@ -4307,13 +4307,19 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
return this->CreateSafeUniqueObjectFileName(objectName, dir_max);
}
bool cmLocalGenerator::UseShortObjectNames() const
bool cmLocalGenerator::UseShortObjectNames(
cmStateEnums::IntermediateDirKind kind) const
{
return this->GlobalGenerator->UseShortObjectNames();
return this->GlobalGenerator->UseShortObjectNames(kind);
}
std::string cmLocalGenerator::GetObjectOutputRoot() const
std::string cmLocalGenerator::GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind) const
{
if (this->UseShortObjectNames(kind)) {
return cmStrCat(this->GetCurrentBinaryDirectory(), '/',
this->GlobalGenerator->GetShortBinaryOutputDir());
}
return cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
}
+7 -2
View File
@@ -24,6 +24,7 @@
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmValue.h"
class cmCompiledGeneratorExpression;
@@ -439,8 +440,12 @@ public:
std::string const& GetCurrentBinaryDirectory() const;
std::string const& GetCurrentSourceDirectory() const;
bool UseShortObjectNames() const;
virtual std::string GetObjectOutputRoot() const;
bool UseShortObjectNames(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const;
virtual std::string GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const;
virtual bool AlwaysUsesCMFPaths() const;
virtual std::string GetShortObjectFileName(cmSourceFile const& source) const;
virtual std::string ComputeShortTargetDirectory(
+3 -2
View File
@@ -163,9 +163,10 @@ void cmLocalNinjaGenerator::Generate()
}
}
std::string cmLocalNinjaGenerator::GetObjectOutputRoot() const
std::string cmLocalNinjaGenerator::GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind) const
{
if (this->UseShortObjectNames()) {
if (this->UseShortObjectNames(kind)) {
return cmStrCat(this->GetBinaryDirectory(), '/',
this->GetGlobalGenerator()->GetShortBinaryOutputDir());
}
+4 -1
View File
@@ -15,6 +15,7 @@
#include "cmLocalCommonGenerator.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
#include "cmStateTypes.h"
class cmCustomCommand;
class cmCustomCommandGenerator;
@@ -62,7 +63,9 @@ public:
{
return this->HomeRelativeOutputPath;
}
std::string GetObjectOutputRoot() const override;
std::string GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const override;
std::string BuildCommandLine(
std::vector<std::string> const& cmdLines, std::string const& outputConfig,
+3 -2
View File
@@ -201,9 +201,10 @@ void cmLocalUnixMakefileGenerator3::Generate()
this->WriteDirectoryInformationFile();
}
std::string cmLocalUnixMakefileGenerator3::GetObjectOutputRoot() const
std::string cmLocalUnixMakefileGenerator3::GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind) const
{
if (this->UseShortObjectNames()) {
if (this->UseShortObjectNames(kind)) {
return cmStrCat(this->GetCurrentBinaryDirectory(), '/',
this->GetGlobalGenerator()->GetShortBinaryOutputDir());
}
+4 -1
View File
@@ -14,6 +14,7 @@
#include "cmDepends.h"
#include "cmGeneratorOptions.h"
#include "cmLocalCommonGenerator.h"
#include "cmStateTypes.h"
class cmCustomCommand;
class cmCustomCommandGenerator;
@@ -43,7 +44,9 @@ public:
*/
void Generate() override;
std::string GetObjectOutputRoot() const override;
std::string GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const override;
// this returns the relative path between the HomeOutputDirectory and this
// local generators StartOutputDirectory
+3 -2
View File
@@ -95,9 +95,10 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
}
}
std::string cmLocalVisualStudioGenerator::GetObjectOutputRoot() const
std::string cmLocalVisualStudioGenerator::GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind) const
{
if (this->UseShortObjectNames()) {
if (this->UseShortObjectNames(kind)) {
return cmStrCat(this->GetCurrentBinaryDirectory(), '/',
this->GetGlobalGenerator()->GetShortBinaryOutputDir());
}
+4 -1
View File
@@ -10,6 +10,7 @@
#include "cmGlobalVisualStudioGenerator.h"
#include "cmLocalGenerator.h"
#include "cmStateTypes.h"
#include "cmVsProjectType.h"
class cmCustomCommand;
@@ -51,7 +52,9 @@ public:
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* = nullptr) override;
std::string GetObjectOutputRoot() const override;
std::string GetObjectOutputRoot(
cmStateEnums::IntermediateDirKind kind =
cmStateEnums::IntermediateDirKind::ObjectFiles) const override;
bool AlwaysUsesCMFPaths() const override;
protected:
+18 -7
View File
@@ -460,20 +460,31 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Collapsed current binary directory
std::string const cbd = cmSystemTools::CollapseFullPath(
std::string(), this->Makefile->GetCurrentBinaryDirectory());
std::string infoDir;
std::string buildDir;
auto idirkind = cmStateEnums::IntermediateDirKind::QtAutogenMetadata;
if (this->GenTarget->GetUseShortObjectNames(idirkind)) {
infoDir = cmSystemTools::CollapseFullPath(
std::string(),
cmStrCat(this->GenTarget->GetSupportDirectory(idirkind),
"/autogen_info"));
buildDir = cmSystemTools::CollapseFullPath(
std::string(),
cmStrCat(this->GenTarget->GetSupportDirectory(idirkind), "/autogen"));
} else {
infoDir = cmStrCat(cbd, "/CMakeFiles/", this->GenTarget->GetName(),
"_autogen.dir");
buildDir = cmStrCat(cbd, '/', this->GenTarget->GetName(), "_autogen");
}
// Info directory
// TODO: Split this? `AutogenInfo.json` is expected to always be under the
// `CMakeFiles` directory, but not all generators places its `<tgt>.dir`
// directories there.
this->Dir.Info = cmStrCat(cbd, "/CMakeFiles/", this->GenTarget->GetName(),
"_autogen.dir");
this->Dir.Info = infoDir;
cmSystemTools::ConvertToUnixSlashes(this->Dir.Info);
// Build directory
this->Dir.Build = this->GenTarget->GetSafeProperty("AUTOGEN_BUILD_DIR");
if (this->Dir.Build.empty()) {
this->Dir.Build =
cmStrCat(cbd, '/', this->GenTarget->GetName(), "_autogen");
this->Dir.Build = buildDir;
}
cmSystemTools::ConvertToUnixSlashes(this->Dir.Build);
this->Dir.RelativeBuild =
+6
View File
@@ -89,6 +89,12 @@ enum ArtifactType
RuntimeBinaryArtifact,
ImportLibraryArtifact
};
enum class IntermediateDirKind
{
ObjectFiles,
QtAutogenMetadata,
};
}
namespace cmTraceEnums {
+11
View File
@@ -935,6 +935,8 @@ void cmake::LoadEnvironmentPresets()
readGeneratorVar("CMAKE_GENERATOR_TOOLSET", this->GeneratorToolset);
this->IntermediateDirStrategy =
cmSystemTools::GetEnvVar("CMAKE_INTERMEDIATE_DIR_STRATEGY");
this->AutogenIntermediateDirStrategy =
cmSystemTools::GetEnvVar("CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY");
}
namespace {
@@ -2609,6 +2611,15 @@ int cmake::ActualConfigure()
"CMAKE_INTERMEDIATE_DIR_STRATEGY", *this->IntermediateDirStrategy,
"Select the intermediate directory strategy", cmStateEnums::INTERNAL);
}
if (!this->State->GetInitializedCacheValue(
"CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY") &&
this->AutogenIntermediateDirStrategy) {
this->AddCacheEntry(
"CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY",
*this->AutogenIntermediateDirStrategy,
"Select the intermediate directory strategy for Autogen",
cmStateEnums::INTERNAL);
}
if (!this->State->GetInitializedCacheValue("CMAKE_TEST_LAUNCHER")) {
cm::optional<std::string> testLauncher =
+1
View File
@@ -769,6 +769,7 @@ protected:
std::string GeneratorPlatform;
std::string GeneratorToolset;
cm::optional<std::string> IntermediateDirStrategy;
cm::optional<std::string> AutogenIntermediateDirStrategy;
bool GeneratorInstanceSet = false;
bool GeneratorPlatformSet = false;
bool GeneratorToolsetSet = false;
@@ -76,7 +76,7 @@ execute_process(
"-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
"-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
"-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
-DCMAKE_INTERMEDIATE_DIR_STRATEGY:STRING=FULL
-DCMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY:STRING=FULL
WORKING_DIRECTORY "${GAT_BDIR}"
OUTPUT_VARIABLE output
RESULT_VARIABLE result)
@@ -1,3 +1,5 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
enable_language(CXX)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
@@ -0,0 +1,10 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE)
enable_language(CXX)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
add_library(dummy SHARED empty.cpp)
target_link_libraries(dummy Qt${with_qt_version}::Core
Qt${with_qt_version}::Widgets
Qt${with_qt_version}::Gui)
@@ -0,0 +1,3 @@
include("${CMAKE_CURRENT_LIST_DIR}/AutogenUseSystemIncludeShortCommon.cmake")
set_target_properties(dummy PROPERTIES AUTOGEN_USE_SYSTEM_INCLUDE OFF)
@@ -0,0 +1,3 @@
include("${CMAKE_CURRENT_LIST_DIR}/AutogenUseSystemIncludeShortCommon.cmake")
set_target_properties(dummy PROPERTIES AUTOGEN_USE_SYSTEM_INCLUDE ON)
@@ -1,3 +1,5 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
enable_language(CXX)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
@@ -0,0 +1,12 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE)
enable_language(CXX)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
set(CMAKE_AUTOMOC ON)
add_library(dummy SHARED empty.cpp)
target_link_libraries(dummy Qt${with_qt_version}::Core
Qt${with_qt_version}::Widgets
Qt${with_qt_version}::Gui)
@@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/CMP0151Short-common.cmake")
@@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/CMP0151Short-common.cmake")
@@ -1,3 +1,5 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
enable_language(CXX)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core)
@@ -38,13 +38,17 @@ if (DEFINED with_qt_version)
set(test_expect_stdout_common "-*${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
endif()
set(test_expect_stdout_1 "${test_expect_stdout_common}")
set(test_expect_stdout_1_short "${test_expect_stdout_common}")
set(test_expect_stdout_2 "${test_expect_stdout_common}")
string(APPEND test_expect_stdout_1 " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
string(APPEND test_expect_stdout_1_short " *(\"[^\"]*|([^ ]|\\ )*)[\\/]\\.o[\\/]9624d702[\\/]autogen[\\/]include")
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
string(APPEND test_expect_stdout_1 "_Debug")
string(APPEND test_expect_stdout_1_short "_Debug")
endif()
string(APPEND test_expect_stdout_2 " *(\"[^\"]*|([^ ]|\\ )*)[\\/]QtCore")
set(test_expect_stdout "${test_expect_stdout_1}.*${test_expect_stdout_2}")
set(test_expect_stdout_short "${test_expect_stdout_1_short}.*${test_expect_stdout_2}")
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151-new-build)
@@ -61,6 +65,24 @@ if (DEFINED with_qt_version)
set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
run_cmake_command(AutogenUseSystemIncludeOn-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)")
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151Short-new-build)
run_cmake_with_options(CMP0151Short-new ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTO${autogen_type}=ON -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout_short}")
run_cmake_command(CMP0151Short-new-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeShortOn-build)
run_cmake_with_options(AutogenUseSystemIncludeShortOn ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTO${autogen_type}=ON -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout_short}")
run_cmake_command(AutogenUseSystemIncludeShortOn-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
endif ()
endif()
if(CMAKE_INCLUDE_FLAG_CXX)
@@ -68,10 +90,13 @@ if (DEFINED with_qt_version)
string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_FLAG_CXX}")
else()
set(test_expect_stdout "-*${CMAKE_INCLUDE_FLAG_CXX}")
set(test_expect_stdout_short "-*${CMAKE_INCLUDE_FLAG_CXX}")
endif()
string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
string(APPEND test_expect_stdout_short " *(\"[^\"]*|([^ ]|\\ )*)[\\/]\\.o[\\/]9624d702[\\/]autogen[\\/]include")
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
string(APPEND test_expect_stdout "_Debug")
string(APPEND test_expect_stdout_short "_Debug")
endif()
block()
@@ -89,6 +114,24 @@ if (DEFINED with_qt_version)
set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
run_cmake_command(AutogenUseSystemIncludeOff-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)")
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151Short-old-build)
run_cmake_with_options(CMP0151Short-old ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTO${autogen_type}=ON -DCMAKE_POLICY_DEFAULT_CMP0151=OLD)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout_short}")
run_cmake_command(CMP0151Short-old-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeShortOff-build)
run_cmake_with_options(AutogenUseSystemIncludeShortOff ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTO${autogen_type}=ON -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout_short}")
run_cmake_command(AutogenUseSystemIncludeShortOff-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
endblock()
endif()
endif()
endblock()
endforeach()
@@ -1,3 +1,5 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
enable_language(CXX)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
@@ -1,3 +1,5 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 11)
@@ -0,0 +1,46 @@
# Read the JSON file into a variable
set(autogenInfoFilePath "${RunCMake_TEST_BINARY_DIR}/.o/4bcad702/autogen_info/AutogenInfo.json")
if(NOT IS_READABLE "${autogenInfoFilePath}")
set(RunCMake_TEST_FAILED "Expected autogen info file missing:\n \"${autogenInfoFilePath}\"")
return()
endif()
file(READ "${autogenInfoFilePath}" jsonRaw)
# If multi-config generator, we are looking for MOC_INCLUDES_<CONFIG>.
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(mocKey "MOC_INCLUDES_Debug") # Pick one arbitrarily (they will all be the same in this test)
# If single-config generator, we are looking for MOC_INCLUDES.
else()
set(mocKey "MOC_INCLUDES")
endif()
string(JSON actualValue GET "${jsonRaw}" "${mocKey}")
# The format of the MOC_INCLUDES entries in AutogenInfo.json depends on how long the paths are.
# For short entries:
# "MOC_INCLUDES" : [ "<SHORT_PATH>" ]
# For long entries:
# "MOC_INCLUDES_Debug" :
# [
# "<SOME_PARTICULARLY_LONG_PATH>"
# ],
# Also, paths given to AUTOMOC_INCLUDE_DIRECTORIES must be absolute paths.
# The code uses SystemTools::FileIsFullPath() to verify this, and it accepts
# a forward slash at the beginning for both Windows (network path) and UNIX platforms.
# Therefore, for the simplicity of this test, use a dummy value "/pass".
# Strip the JSON format around the string for a true before/after comparison.
string(REPLACE "[ \"" "" actualValue ${actualValue})
string(REPLACE "\" ]" "" actualValue ${actualValue})
# Final pass/fail comparison.
set(expectedValue "/pass")
if (NOT actualValue STREQUAL expectedValue)
set(RunCMake_TEST_FAILED "AUTOMOC_INCLUDE_DIRECTORIES override property not honored.")
string(APPEND RunCMake_TEST_FAILURE_MESSAGE
"Expected MOC_INCLUDES in AutogenInfo.json to have ${expectedValue} but found ${actualValue}."
)
endif()
@@ -0,0 +1,18 @@
set(CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 11)
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core)
# Create a test library with an arbitrary include directory to later override with the property
add_library(foo STATIC ../Autogen_common/example.cpp)
target_include_directories(foo PRIVATE ../Autogen_common/example.h)
# Set AUTOMOC_INCLUDE_DIRECTORIES with a test value to verify it replaces the above include directory
# in AutogenInfo.json's MOC_INCLUDES list.
# See comments in the -check.cmake counterpart for more information about this test.
set_target_properties(foo PROPERTIES
AUTOMOC ON
AUTOMOC_INCLUDE_DIRECTORIES "/pass"
)
@@ -7,4 +7,7 @@ if (DEFINED with_qt_version)
"-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
)
run_cmake(AutoMocIncludeDirectories)
if (CMAKE_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)")
run_cmake(AutoMocIncludeDirectoriesShort)
endif ()
endif()
@@ -0,0 +1,5 @@
CMake Error:
Unsupported autogen intermediate directory strategy 'INVALID'
CMake Generate step failed. Build files cannot be regenerated correctly.
@@ -0,0 +1,5 @@
CMake Error:
Unsupported autogen intermediate directory strategy 'INVALID'
CMake Generate step failed. Build files cannot be regenerated correctly.
@@ -1,20 +1,29 @@
include(RunCMake)
function(run_cmake_intdir_strategy base strategy)
unset(ENV{CMAKE_INTERMEDIATE_DIR_STRATEGY})
function(run_cmake_intdir_strategy base strategy kind)
if (kind STREQUAL "Object")
set(varname "CMAKE_INTERMEDIATE_DIR_STRATEGY")
elseif (kind STREQUAL "Autogen")
set(varname "CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY")
else ()
message(FATAL_ERROR "unsupported kind: ${kind}")
endif ()
unset(ENV{${varname}})
if (base STREQUAL "IntDirStrategyCache")
set(RunCMake_TEST_OPTIONS -DCMAKE_INTERMEDIATE_DIR_STRATEGY=${strategy})
set(RunCMake_TEST_OPTIONS -D${varname}=${strategy})
elseif (base STREQUAL "IntDirStrategyEnv")
set(ENV{CMAKE_INTERMEDIATE_DIR_STRATEGY} "${strategy}")
set(ENV{${varname}} "${strategy}")
else ()
message(FATAL_ERROR "unsupported base: ${base}")
endif ()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${base}${strategy}-build)
run_cmake(${base}${strategy})
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${kind}${base}${strategy}-build)
run_cmake(${kind}${base}${strategy})
endfunction()
foreach (strategy IN ITEMS INVALID FULL SHORT)
run_cmake_intdir_strategy(IntDirStrategyCache ${strategy})
run_cmake_intdir_strategy(IntDirStrategyEnv ${strategy})
foreach (kind IN ITEMS Object Autogen)
foreach (strategy IN ITEMS INVALID FULL SHORT)
run_cmake_intdir_strategy(IntDirStrategyCache ${strategy} ${kind})
run_cmake_intdir_strategy(IntDirStrategyEnv ${strategy} ${kind})
endforeach ()
endforeach ()