From f500a784d008566d6eb6301b7c6a0f07847b856d Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 2 Jun 2016 10:57:10 -0400 Subject: Fix crash on $ genex (#16134) Policy CMP0026 deprecated the LOCATION property, and we have long provided a $ generator expression. However, if a project tries to use $ we should at least not crash. The compatibility implementation of the LOCATION property uses cmGlobalGenerator::CreateGenerationObjects to create the structures needed to evaluate the property before generation starts. The implementation assumed that accessing the property could only be done during configuration (via the typical get_property command use case). The $ genex causes the LOCATION property to be accessed during generation. Calling CreateGenerationObjects during generation blows away all the objects currently being used for generation and is not safe. Add a condition to call it only when configuration is not finished. --- Source/cmTarget.cxx | 12 +++++++++--- Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake | 1 + .../GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt | 10 ++++++++++ .../GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake | 3 +++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5e0d2b7..f435a1d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1131,7 +1131,9 @@ const char* cmTarget::GetProperty(const std::string& prop, // target because the configuration type may not be known at // CMake time. cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); - gg->CreateGenerationObjects(); + if (!gg->GetConfigureDoneCMP0026()) { + gg->CreateGenerationObjects(); + } cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName()); this->Properties.SetProperty(propLOCATION, gt->GetLocationForBuild()); } @@ -1150,7 +1152,9 @@ const char* cmTarget::GetProperty(const std::string& prop, prop, this->ImportedGetFullPath(configName, false).c_str()); } else { cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); - gg->CreateGenerationObjects(); + if (!gg->GetConfigureDoneCMP0026()) { + gg->CreateGenerationObjects(); + } cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName()); this->Properties.SetProperty( prop, gt->GetFullPath(configName, false).c_str()); @@ -1168,7 +1172,9 @@ const char* cmTarget::GetProperty(const std::string& prop, prop, this->ImportedGetFullPath(configName, false).c_str()); } else { cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); - gg->CreateGenerationObjects(); + if (!gg->GetConfigureDoneCMP0026()) { + gg->CreateGenerationObjects(); + } cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName()); this->Properties.SetProperty( prop, gt->GetFullPath(configName, false).c_str()); diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 45175d8..625bab2 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -28,6 +28,7 @@ run_cmake(COMPILE_LANGUAGE-add_test) run_cmake(COMPILE_LANGUAGE-unknown-lang) run_cmake(TARGET_FILE-recursion) run_cmake(OUTPUT_NAME-recursion) +run_cmake(TARGET_PROPERTY-LOCATION) run_cmake(ImportedTarget-TARGET_PDB_FILE) if(LINKER_SUPPORTS_PDB) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt new file mode 100644 index 0000000..e4dbb71 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION-stderr.txt @@ -0,0 +1,10 @@ +CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0026 is not set: Disallow use of the LOCATION target property. + Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy + command to set the policy and suppress this warning. + + The LOCATION property should not be read from target "foo". Use the target + name directly with add_custom_command, or use the generator expression + \$, as appropriate. + +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake new file mode 100644 index 0000000..8929cdb --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-LOCATION.cmake @@ -0,0 +1,3 @@ +enable_language(C) +add_library(foo empty.c) +add_custom_target(drive COMMAND ${CMAKE_COMMAND} -E echo $) -- cgit v0.12