Merge branch 'backport-3.15-fix-EXCLUDE_FROM_ALL-subdir-all'

Resolve conflicts with changes since the 3.15 series:

* Convert `cmSystemTools::IsOn` => `cmIsOn`.
* Move one "EXCLUDE_FROM_ALL" target property logic fix to
  its new location in `cmMakefile::AddNewUtilityTarget`.
This commit is contained in:
Brad King 2019-09-30 09:34:57 -04:00
commit dce58afd30
21 changed files with 203 additions and 107 deletions

View File

@ -1,15 +1,13 @@
EXCLUDE_FROM_ALL
----------------
Exclude the directory from the all target of its parent.
Set this directory property to a true value on a subdirectory to exclude
its targets from the "all" target of its ancestors. If excluded, running
e.g. ``make`` in the parent directory will not build targets the
subdirectory by default. This does not affect the "all" target of the
subdirectory itself. Running e.g. ``make`` inside the subdirectory will
still build its targets.
A property on a directory that indicates if its targets are excluded
from the default build target. If it is not, then with a Makefile for
example typing make will cause the targets to be built. The same
concept applies to the default build of other generators.
Targets inherit the :prop_tgt:`EXCLUDE_FROM_ALL` property from the directory
that they are created in. When a directory is excluded, all of its targets will
have :prop_tgt:`EXCLUDE_FROM_ALL` set to ``TRUE``. After creating such a target
you can change its :prop_tgt:`EXCLUDE_FROM_ALL` property to ``FALSE``. This
will cause the target to be included in the default build target.
If the :prop_tgt:`EXCLUDE_FROM_ALL` target property is set on a target
then its value determines whether the target is included in the "all"
target of this directory and its ancestors.

View File

@ -1,12 +1,15 @@
EXCLUDE_FROM_ALL
----------------
Exclude the target from the all target.
Set this target property to a true (or false) value to exclude (or include)
the target from the "all" target of the containing directory and its
ancestors. If excluded, running e.g. ``make`` in the containing directory
or its ancestors will not build the target by default.
A property on a target that indicates if the target is excluded from
the default build target. If it is not, then with a Makefile for
example typing make will cause this target to be built. The same
concept applies to the default build of other generators.
If this target property is not set then the target will be included in
the "all" target of the containing directory. Furthermore, it will be
included in the "all" target of its ancestor directories unless the
:prop_dir:`EXCLUDE_FROM_ALL` directory property is set.
With ``EXCLUDE_FROM_ALL`` set to false or not set at all, the target
will be brought up to date as part of doing a ``make install`` or its
@ -16,6 +19,3 @@ target has undefined behavior. Note that such a target can still safely
be listed in an :command:`install(TARGETS)` command as long as the install
components the target belongs to are not part of the set of components
that anything tries to install.
This property is enabled by default for targets that are created in
directories that have :prop_dir:`EXCLUDE_FROM_ALL` set to ``TRUE``.

View File

@ -428,3 +428,11 @@ Changes made since CMake 3.14.0 include the following.
policy :policy:`CMP0088` ``NEW`` behavior accidentally interpreted
a relative path to the ``.y`` input as relative to the build tree
directory instead of the source tree directory. This has been fixed.
3.14.7
------
* In CMake 3.14.0 through 3.14.6, the :prop_dir:`EXCLUDE_FROM_ALL`
directory property was regressed from pre-3.14 behavior and caused
targets within the directory to be excluded even from its own "all".
This has been fixed.

View File

@ -376,3 +376,12 @@ Changes made since CMake 3.15.0 include the following.
* ``CrayPrgEnv`` compiler wrapper support has been updated for the 19.06
release of the Cray Programming Environment for which the default linking
mode on XC Cray systems is now dynamic instead of static.
3.15.4
------
* In CMake 3.15.0 through 3.15.3, the :prop_dir:`EXCLUDE_FROM_ALL`
directory property was regressed from pre-3.14 behavior and caused
targets within the directory to be excluded even from its own "all".
This has been fixed.
The bug also existed in 3.14.0 through 3.14.6 and is fixed in 3.14.7.

View File

@ -2037,10 +2037,18 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
return this->IsExcluded(rootSnp, snp);
}
bool cmGlobalGenerator::IsExcluded(cmGeneratorTarget* target) const
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
cmGeneratorTarget* target) const
{
return target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
target->GetPropertyAsBool("EXCLUDE_FROM_ALL");
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
if (const char* exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
return cmIsOn(exclude);
}
// This target is included in its directory. Check whether the
// directory is excluded.
return this->IsExcluded(root, target->GetLocalGenerator());
}
void cmGlobalGenerator::GetEnabledLanguages(

View File

@ -511,7 +511,7 @@ protected:
bool IsExcluded(cmStateSnapshot const& root,
cmStateSnapshot const& snp) const;
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
bool IsExcluded(cmGeneratorTarget* target) const;
bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
virtual void InitializeProgressMarks() {}
struct GlobalTargetInfo

View File

@ -302,9 +302,9 @@ public:
return LocalGenerators;
}
bool IsExcluded(cmGeneratorTarget* target)
bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target)
{
return cmGlobalGenerator::IsExcluded(target);
return cmGlobalGenerator::IsExcluded(root, target);
}
int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }

View File

@ -230,6 +230,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
depends.push_back(this->EmptyRuleHackDepends);
}
// Write and empty all:
lg->WriteMakeRule(makefileStream, "The main recursive all target", "all",
depends, no_commands, true);
// Write an empty preinstall:
lg->WriteMakeRule(makefileStream, "The main recursive preinstall target",
"preinstall", depends, no_commands, true);
// Write out the "special" stuff
lg->WriteSpecialTargetsTop(makefileStream);
@ -460,8 +468,13 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
ruleFileStream << "\n\n";
}
// Write directory-level rules for "all".
this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false);
if (!lg->IsRootMakefile()) {
// Write directory-level rules for "all".
this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false);
// Write directory-level rules for "preinstall".
this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
}
// Write directory-level rules for "clean".
{
@ -469,9 +482,6 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
lg->AppendDirectoryCleanCommand(cmds);
this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false, cmds);
}
// Write directory-level rules for "preinstall".
this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
}
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
@ -685,6 +695,15 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
localName, depends, commands, true);
// add the all/all dependency
if (!this->IsExcluded(this->LocalGenerators[0], gtarget)) {
depends.clear();
depends.push_back(localName);
commands.clear();
lg->WriteMakeRule(ruleFileStream, "Include target in all.", "all",
depends, commands, true);
}
// Write the rule.
commands.clear();
@ -739,7 +758,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
"Pre-install relink rule for target.", localName,
depends, commands, true);
if (!this->IsExcluded(gtarget)) {
if (!this->IsExcluded(this->LocalGenerators[0], gtarget)) {
depends.clear();
depends.push_back(localName);
commands.clear();

View File

@ -214,7 +214,7 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
tgt->IsImported()) {
continue;
}
if (!this->IsExcluded(tgt)) {
if (!this->IsExcluded(gen[0], tgt)) {
allBuild->AddUtility(tgt->GetName());
}
}

View File

@ -563,7 +563,7 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
cmObjectLibraryCommands::Accept);
}
if (!this->IsExcluded(target)) {
if (!this->IsExcluded(gens[0], target)) {
allbuild->AddUtility(target->GetName());
}
}

View File

@ -89,7 +89,9 @@ void cmLocalNinjaGenerator::Generate()
if (tg) {
tg->Generate();
// Add the target to "all" if required.
if (!this->GetGlobalNinjaGenerator()->IsExcluded(target)) {
if (!this->GetGlobalNinjaGenerator()->IsExcluded(
this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0],
target)) {
this->GetGlobalNinjaGenerator()->AddDependencyToAll(target);
}
}

View File

@ -1776,7 +1776,7 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot);
this->GetGlobalGenerator()->AddMakefile(subMf);
if (excludeFromAll || this->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
if (excludeFromAll) {
subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
@ -2051,9 +2051,7 @@ cmTarget* cmMakefile::AddLibrary(const std::string& lname,
// over changes in CMakeLists.txt, making the information stale and
// hence useless.
target->ClearDependencyInformation(*this);
if (excludeFromAll ||
(type != cmStateEnums::INTERFACE_LIBRARY &&
this->GetPropertyAsBool("EXCLUDE_FROM_ALL"))) {
if (excludeFromAll) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
target->AddSources(srcs);
@ -2066,7 +2064,7 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName,
bool excludeFromAll)
{
cmTarget* target = this->AddNewTarget(cmStateEnums::EXECUTABLE, exeName);
if (excludeFromAll || this->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
if (excludeFromAll) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
target->AddSources(srcs);
@ -2093,7 +2091,7 @@ cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName,
{
cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName);
target->SetIsGeneratorProvided(origin == cmCommandOrigin::Generator);
if (excludeFromAll || this->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
if (excludeFromAll) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
return target;

View File

@ -92,9 +92,12 @@ function(run_cmake test)
set(maybe_input_file "")
endif()
if(RunCMake_TEST_COMMAND)
if(NOT RunCMake_TEST_COMMAND_WORKING_DIRECTORY)
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
endif()
execute_process(
COMMAND ${RunCMake_TEST_COMMAND}
WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
WORKING_DIRECTORY "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}"
OUTPUT_VARIABLE actual_stdout
ERROR_VARIABLE ${actual_stderr_var}
RESULT_VARIABLE actual_result

View File

@ -4,3 +4,11 @@ add_subdirectory(ExcludeFromAll EXCLUDE_FROM_ALL)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE foo)
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
set(main_exe \"$<TARGET_FILE:main>\")
set(foo_lib \"$<TARGET_FILE:foo>\")
set(bar_lib \"$<TARGET_FILE:bar>\")
set(zot_lib \"$<TARGET_FILE:zot>\")
set(subinc_lib \"$<TARGET_FILE:subinc>\")
")

View File

@ -1,20 +1,11 @@
add_library(bar STATIC bar.cpp)
project(ExcludeFromAllSub NONE)
add_library(bar STATIC EXCLUDE_FROM_ALL bar.cpp)
add_library(zot STATIC zot.cpp)
add_library(foo STATIC foo.cpp)
add_library(baz STATIC foo.cpp)
set_target_properties(baz PROPERTIES EXCLUDE_FROM_ALL OFF)
file(GENERATE
OUTPUT "${CMAKE_BINARY_DIR}/main.txt"
CONTENT "$<TARGET_FILE_NAME:main>")
file(GENERATE
OUTPUT "${CMAKE_BINARY_DIR}/bar.txt"
CONTENT "$<TARGET_FILE_NAME:bar>")
file(GENERATE
OUTPUT "${CMAKE_BINARY_DIR}/baz.txt"
CONTENT "$<TARGET_FILE_NAME:baz>")
target_include_directories(foo PUBLIC .)
add_library(subinc STATIC subinc.cpp)
set_target_properties(subinc PROPERTIES EXCLUDE_FROM_ALL OFF)

View File

@ -0,0 +1,32 @@
if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
if(RunCMake_TEST_FAILED)
return()
endif()
foreach(file
"${foo_lib}"
"${subinc_lib}"
"${zot_lib}"
)
if(NOT EXISTS "${file}")
set(RunCMake_TEST_FAILED
"Artifact should exist but is missing:\n ${file}")
return()
endif()
endforeach()
foreach(file
"${main_exe}"
"${bar_lib}"
)
if(EXISTS "${file}")
set(RunCMake_TEST_FAILED
"Artifact should be missing but exists:\n ${file}")
return()
endif()
endforeach()
else()
set(RunCMake_TEST_FAILED "
'${RunCMake_TEST_BINARY_DIR}/check-debug.cmake' missing
")
endif()

View File

@ -1,44 +1,35 @@
# Use globbing to check if exes / libs were built because determining
# exactly where these files will live inside a CMake -P script is
# pretty challenging.
file(READ "${RunCMake_TEST_BINARY_DIR}/main.txt" main_exe)
file(READ "${RunCMake_TEST_BINARY_DIR}/bar.txt" bar_lib)
file(READ "${RunCMake_TEST_BINARY_DIR}/baz.txt" baz_lib)
set(found_main FALSE)
file(GLOB_RECURSE files
LIST_DIRECTORIES FALSE
RELATIVE "${RunCMake_TEST_BINARY_DIR}"
"${RunCMake_TEST_BINARY_DIR}/*")
foreach (file IN LISTS files)
if (file MATCHES "${main_exe}")
set(found_main TRUE)
if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
if(RunCMake_TEST_FAILED)
return()
endif()
endforeach()
if (NOT found_main)
set(RunCMake_TEST_FAILED "'main' missing from ${RunCMake_TEST_BINARY_DIR}")
endif()
set(found_bar FALSE)
set(found_baz FALSE)
file(GLOB_RECURSE files
LIST_DIRECTORIES FALSE
RELATIVE "${RunCMake_TEST_BINARY_DIR}/ExcludeFromAll"
"${RunCMake_TEST_BINARY_DIR}/ExcludeFromAll/*")
foreach (file IN LISTS files)
if (file MATCHES "${bar_lib}")
set(found_bar TRUE)
endif()
if (file MATCHES "${baz_lib}")
set(found_baz TRUE)
endif()
endforeach()
if (found_bar)
set(RunCMake_TEST_FAILED
"'bar' was not excluded from ${RunCMake_TEST_BINARY_DIR}/ExcludeFromAll")
endif()
if (NOT found_baz)
set(RunCMake_TEST_FAILED
"'baz' missing from ${RunCMake_TEST_BINARY_DIR}/ExcludeFromAll")
foreach(file
"${foo_lib}"
"${subinc_lib}"
"${main_exe}"
)
if(EXISTS "${file}")
# Remove for next step of test.
file(REMOVE "${file}")
else()
set(RunCMake_TEST_FAILED
"Artifact should exist but is missing:\n ${file}")
return()
endif()
endforeach()
foreach(file
"${zot_lib}"
"${bar_lib}"
)
if(EXISTS "${file}")
set(RunCMake_TEST_FAILED
"Artifact should be missing but exists:\n ${file}")
return()
endif()
endforeach()
else()
set(RunCMake_TEST_FAILED "
'${RunCMake_TEST_BINARY_DIR}/check-debug.cmake' missing
")
endif()

View File

@ -0,0 +1,4 @@
int subinc()
{
return 0;
}

View File

@ -0,0 +1,4 @@
int zot()
{
return 0;
}

View File

@ -27,14 +27,34 @@ run_cmake_install(CMP0082-OLD -DCMP0082_VALUE=OLD)
run_cmake_install(CMP0082-NEW -DCMP0082_VALUE=NEW)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExcludeFromAll-build)
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
endif()
run_cmake(ExcludeFromAll)
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake-check-file ExcludeFromAll/check.cmake)
run_cmake_command(ExcludeFromAll-build ${CMAKE_COMMAND} --build .)
unset(RunCMake_TEST_BINARY_DIR)
run_cmake_command(ExcludeFromAll-build ${CMAKE_COMMAND} --build . --config Debug)
if(RunCMake_GENERATOR STREQUAL "Ninja")
if(WIN32)
set(slash [[\]])
else()
set(slash [[/]])
endif()
set(RunCMake-check-file ExcludeFromAll/check-sub.cmake)
run_cmake_command(ExcludeFromAll-build-sub ${CMAKE_COMMAND} --build . --target "ExcludeFromAll${slash}all")
elseif(RunCMake_GENERATOR MATCHES "Make")
set(RunCMake-check-file ExcludeFromAll/check-sub.cmake)
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY ${RunCMake_BINARY_DIR}/ExcludeFromAll-build/ExcludeFromAll)
run_cmake_command(ExcludeFromAll-build-sub "${RunCMake_MAKE_PROGRAM}")
elseif(RunCMake_GENERATOR MATCHES "^Visual Studio [1-9][0-9]")
set(RunCMake-check-file ExcludeFromAll/check-sub.cmake)
run_cmake_command(ExcludeFromAll-build-sub ${CMAKE_COMMAND} --build ExcludeFromAll --config Debug)
elseif(RunCMake_GENERATOR STREQUAL "Xcode")
set(RunCMake-check-file ExcludeFromAll/check-sub.cmake)
set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY ${RunCMake_BINARY_DIR}/ExcludeFromAll-build/ExcludeFromAll)
run_cmake_command(ExcludeFromAll-build-sub xcodebuild -configuration Debug)
endif()
unset(RunCMake-check-file)
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_OPTIONS)
unset(RunCMake_TEST_BINARY_DIR)