| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /*=========================================================================
- Program: CMake - Cross-Platform Makefile Generator
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
- Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
- See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
- =========================================================================*/
- #include "cmGlobalVisualStudioGenerator.h"
- #include "cmLocalGenerator.h"
- #include "cmMakefile.h"
- #include "cmTarget.h"
- //----------------------------------------------------------------------------
- cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator()
- {
- }
- //----------------------------------------------------------------------------
- cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator()
- {
- }
- //----------------------------------------------------------------------------
- void cmGlobalVisualStudioGenerator::FixUtilityDepends()
- {
- // For VS versions before 8:
- //
- // When a target that links contains a project-level dependency on a
- // library target that library is automatically linked. In order to
- // allow utility-style project-level dependencies that do not
- // actually link we need to automatically insert an intermediate
- // custom target.
- //
- // Here we edit the utility dependencies of a target to add the
- // intermediate custom target when necessary.
- for(unsigned i = 0; i < this->LocalGenerators.size(); ++i)
- {
- cmTargets* targets =
- &(this->LocalGenerators[i]->GetMakefile()->GetTargets());
- for(cmTargets::iterator tarIt = targets->begin();
- tarIt != targets->end(); ++tarIt)
- {
- this->FixUtilityDependsForTarget(tarIt->second);
- }
- }
- }
- //----------------------------------------------------------------------------
- void
- cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget(cmTarget& target)
- {
- // Only targets that link need to be fixed.
- if(target.GetType() != cmTarget::STATIC_LIBRARY &&
- target.GetType() != cmTarget::SHARED_LIBRARY &&
- target.GetType() != cmTarget::MODULE_LIBRARY &&
- target.GetType() != cmTarget::EXECUTABLE)
- {
- return;
- }
- // Look at each utility dependency.
- for(std::set<cmStdString>::const_iterator ui =
- target.GetUtilities().begin();
- ui != target.GetUtilities().end(); ++ui)
- {
- if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
- {
- if(depTarget->GetType() == cmTarget::STATIC_LIBRARY ||
- depTarget->GetType() == cmTarget::SHARED_LIBRARY ||
- depTarget->GetType() == cmTarget::MODULE_LIBRARY)
- {
- // This utility dependency will cause an attempt to link. If
- // the depender does not already link the dependee we need an
- // intermediate target.
- if(!this->CheckTargetLinks(target, ui->c_str()))
- {
- this->CreateUtilityDependTarget(*depTarget);
- }
- }
- }
- }
- }
- //----------------------------------------------------------------------------
- void
- cmGlobalVisualStudioGenerator::CreateUtilityDependTarget(cmTarget& target)
- {
- // This target is a library on which a utility dependency exists.
- // We need to create an intermediate custom target to hook up the
- // dependency without causing a link.
- const char* altName = target.GetProperty("ALTERNATIVE_DEPENDENCY_NAME");
- if(!altName)
- {
- // Create the intermediate utility target.
- std::string altNameStr = target.GetName();
- altNameStr += "_UTILITY";
- const std::vector<std::string> no_depends;
- cmCustomCommandLines no_commands;
- const char* no_working_dir = 0;
- const char* no_comment = 0;
- target.GetMakefile()->AddUtilityCommand(altNameStr.c_str(), true,
- no_working_dir, no_depends,
- no_commands, false, no_comment);
- target.SetProperty("ALTERNATIVE_DEPENDENCY_NAME", altNameStr.c_str());
- // Most targets have a GUID created in ConfigureFinalPass. Since
- // that has already been called, create one for this target now.
- this->CreateGUID(altNameStr.c_str());
- // The intermediate target should depend on the original target.
- if(cmTarget* alt = this->FindTarget(0, altNameStr.c_str()))
- {
- alt->AddUtility(target.GetName());
- }
- }
- }
- //----------------------------------------------------------------------------
- bool cmGlobalVisualStudioGenerator::CheckTargetLinks(cmTarget& target,
- const char* name)
- {
- // Return whether the given target links to a target with the given name.
- if(target.GetType() == cmTarget::STATIC_LIBRARY)
- {
- // Static libraries never link to anything.
- return false;
- }
- cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator i = libs.begin();
- i != libs.end(); ++i)
- {
- if(i->first == name)
- {
- return true;
- }
- }
- return false;
- }
- //----------------------------------------------------------------------------
- const char*
- cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
- const char* name)
- {
- // Handle the external MS project special case.
- if(strncmp(name, "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
- {
- // Note from Ken:
- // kind of weird removing the first 27 letters. my
- // recommendatsions: use cmCustomCommand::GetCommand() to get the
- // project name or get rid of the target name starting with
- // "INCLUDE_EXTERNAL_MSPROJECT_" and use another indicator/flag
- // somewhere. These external project names shouldn't conflict
- // with cmake target names anyways.
- return name+27;
- }
- // Possibly depend on an intermediate utility target to avoid
- // linking.
- if(target.GetType() == cmTarget::STATIC_LIBRARY ||
- target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY ||
- target.GetType() == cmTarget::EXECUTABLE)
- {
- // The depender is a target that links. Lookup the dependee to
- // see if it provides an alternative dependency name.
- if(cmTarget* depTarget = this->FindTarget(0, name))
- {
- // Check for an alternative name created by FixUtilityDepends.
- if(const char* altName =
- depTarget->GetProperty("ALTERNATIVE_DEPENDENCY_NAME"))
- {
- // The alternative name is needed only if the depender does
- // not really link to the dependee.
- if(!this->CheckTargetLinks(target, name))
- {
- return altName;
- }
- }
- }
- }
- // No special case. Just use the original dependency name.
- return name;
- }
|