/*============================================================================ CMake - Cross Platform Makefile Generator Copyright 2000-2012 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ #include "cmGeneratorTarget.h" #include "cmTarget.h" #include "cmMakefile.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" #include "cmSourceFile.h" //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) { this->Makefile = this->Target->GetMakefile(); this->LocalGenerator = this->Makefile->GetLocalGenerator(); this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); this->ClassifySources(); this->LookupObjectLibraries(); } //---------------------------------------------------------------------------- void cmGeneratorTarget::ClassifySources() { bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY; std::vector badObjLib; std::vector const& sources = this->Target->GetSourceFiles(); for(std::vector::const_iterator si = sources.begin(); si != sources.end(); ++si) { cmSourceFile* sf = *si; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); cmTarget::SourceFileFlags tsFlags = this->Target->GetTargetSourceFileFlags(sf); if(sf->GetCustomCommand()) { this->CustomCommands.push_back(sf); } else if(tsFlags.Type != cmTarget::SourceFileTypeNormal) { this->OSXContent.push_back(sf); if(isObjLib) { badObjLib.push_back(sf); } } else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY")) { this->HeaderSources.push_back(sf); } else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { this->ExternalObjects.push_back(sf); if(isObjLib) { badObjLib.push_back(sf); } } else if(ext == "def") { this->ModuleDefinitionFile = sf->GetFullPath(); if(isObjLib) { badObjLib.push_back(sf); } } else if(ext == "idl") { this->IDLSources.push_back(sf); if(isObjLib) { badObjLib.push_back(sf); } } else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str())) { // We only get here if a source file is not an external object // and has an extension that is listed as an ignored file type. // No message or diagnosis should be given. this->ExtraSources.push_back(sf); } else if(sf->GetLanguage()) { this->ObjectSources.push_back(sf); } else { this->ExtraSources.push_back(sf); if(isObjLib && ext != "txt") { badObjLib.push_back(sf); } } } if(!badObjLib.empty()) { cmOStringStream e; e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n"; for(std::vector::iterator i = badObjLib.begin(); i != badObjLib.end(); ++i) { e << " " << (*i)->GetLocation().GetName() << "\n"; } e << "but may contain only headers and sources that compile."; this->GlobalGenerator->GetCMakeInstance() ->IssueMessage(cmake::FATAL_ERROR, e.str(), this->Target->GetBacktrace()); } } //---------------------------------------------------------------------------- void cmGeneratorTarget::LookupObjectLibraries() { std::vector const& objLibs = this->Target->GetObjectLibraries(); for(std::vector::const_iterator oli = objLibs.begin(); oli != objLibs.end(); ++oli) { std::string const& objLibName = *oli; if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str())) { if(objLib->GetType() == cmTarget::OBJECT_LIBRARY) { if(this->Target->GetType() != cmTarget::EXECUTABLE && this->Target->GetType() != cmTarget::STATIC_LIBRARY && this->Target->GetType() != cmTarget::SHARED_LIBRARY && this->Target->GetType() != cmTarget::MODULE_LIBRARY) { this->GlobalGenerator->GetCMakeInstance() ->IssueMessage(cmake::FATAL_ERROR, "Only executables and non-OBJECT libraries may " "reference target objects.", this->Target->GetBacktrace()); return; } this->Target->AddUtility(objLib->GetName()); this->ObjectLibraries.push_back(objLib); } else { cmOStringStream e; e << "Objects of target \"" << objLibName << "\" referenced but is not an OBJECT library."; this->GlobalGenerator->GetCMakeInstance() ->IssueMessage(cmake::FATAL_ERROR, e.str(), this->Target->GetBacktrace()); return; } } else { cmOStringStream e; e << "Objects of target \"" << objLibName << "\" referenced but no such target exists."; this->GlobalGenerator->GetCMakeInstance() ->IssueMessage(cmake::FATAL_ERROR, e.str(), this->Target->GetBacktrace()); return; } } } //---------------------------------------------------------------------------- void cmGeneratorTarget::UseObjectLibraries(std::vector& objs) { for(std::vector::const_iterator ti = this->ObjectLibraries.begin(); ti != this->ObjectLibraries.end(); ++ti) { cmTarget* objLib = *ti; cmGeneratorTarget* ogt = this->GlobalGenerator->GetGeneratorTarget(objLib); for(std::vector::const_iterator si = ogt->ObjectSources.begin(); si != ogt->ObjectSources.end(); ++si) { std::string obj = ogt->ObjectDirectory; obj += ogt->Objects[*si]; objs.push_back(obj); } } }