diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 6b8d78de53..319e847a52 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -539,7 +539,7 @@ cmGlobalUnixMakefileGenerator3 this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false); // Write directory-level rules for "preinstall". - this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", false, true); + this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true); } @@ -677,6 +677,23 @@ cmGlobalUnixMakefileGenerator3 (makefileName.c_str(), makeTargetName.c_str())); lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", localName.c_str(), depends, commands, true); + + // Add a local name for the rule to relink the target before + // installation. + if(t->second.NeedRelinkBeforeInstall()) + { + makeTargetName = lg->GetRelativeTargetDirectory(t->second); + makeTargetName += "/preinstall"; + localName = t->second.GetName(); + localName += "/preinstall"; + depends.clear(); + commands.clear(); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(), makeTargetName.c_str())); + lg->WriteMakeRule(ruleFileStream, + "Manual pre-install relink rule for target.", + localName.c_str(), depends, commands, true); + } } } } diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index bb51f9c88f..b0e9ff728c 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -144,6 +144,9 @@ public: "On non-DLL platforms mySharedLib will be installed to /lib " "and /some/full/path." "\n" + "Installing a target with EXCLUDE_FROM_ALL set to true has " + "undefined behavior." + "\n" "The FILES signature:\n" " INSTALL(FILES files... DESTINATION \n" " [PERMISSIONS permissions...]\n" diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index fc088dfd63..f5be726f1a 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -45,6 +45,17 @@ cmInstallTargetGenerator //---------------------------------------------------------------------------- void cmInstallTargetGenerator::GenerateScript(std::ostream& os) { + // Warn if installing an exclude-from-all target. + if(this->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL")) + { + cmOStringStream msg; + msg << "WARNING: Target \"" << this->Target->GetName() + << "\" has EXCLUDE_FROM_ALL set and will not be built by default " + << "but an install rule has been provided for it. CMake does " + << "not define behavior for this case."; + cmSystemTools::Message(msg.str().c_str(), "Warning"); + } + // Track indentation. Indent indent; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 3ba20f8d87..19a00349c3 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -353,10 +353,10 @@ void cmLocalUnixMakefileGenerator3 depends.clear(); // Build the target for this pass. - std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); - tmp += "Makefile2"; + std::string makefile2 = cmake::GetCMakeFilesDirectoryPostSlash(); + makefile2 += "Makefile2"; commands.push_back(this->GetRecursiveMakeCall - (tmp.c_str(),localName.c_str())); + (makefile2.c_str(),localName.c_str())); this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); @@ -390,6 +390,26 @@ void cmLocalUnixMakefileGenerator3 this->Makefile->GetStartOutputDirectory()); this->WriteMakeRule(ruleFileStream, "fast build rule for target.", localName.c_str(), depends, commands, true); + + // Add a local name for the rule to relink the target before + // installation. + if(t->second.NeedRelinkBeforeInstall()) + { + makeTargetName = this->GetRelativeTargetDirectory(t->second); + makeTargetName += "/preinstall"; + localName = t->second.GetName(); + localName += "/preinstall"; + depends.clear(); + commands.clear(); + commands.push_back(this->GetRecursiveMakeCall + (makefile2.c_str(), makeTargetName.c_str())); + this->CreateCDCommand(commands, + this->Makefile->GetHomeOutputDirectory(), + this->Makefile->GetStartOutputDirectory()); + this->WriteMakeRule(ruleFileStream, + "Manual pre-install relink rule for target.", + localName.c_str(), depends, commands, true); + } } } } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 42bf04323e..a048cc4da4 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -123,8 +123,9 @@ void cmTarget::DefineProperties(cmake *cm) "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.", - false); + "The same concept applies to the default build of other generators. " + "Installing a target with EXCLUDE_FROM_ALL set to true has " + "undefined behavior."); cm->DefineProperty ("INSTALL_NAME_DIR", cmProperty::TARGET,