diff options
24 files changed, 483 insertions, 318 deletions
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index 874c816..1b2f8c6 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -32,7 +32,7 @@ bool cmAddDependenciesCommand::InitialPass( cmTarget* target = this->GetMakefile()->GetLocalGenerator()-> - GetGlobalGenerator()->FindTarget(0, target_name.c_str()); + GetGlobalGenerator()->FindTarget(0, target_name.c_str(), false); if(target) { std::vector<std::string>::const_iterator s = args.begin(); diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index e791a82..ad2044c 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -32,6 +32,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args) bool use_win32 = false; bool use_macbundle = false; bool excludeFromAll = false; + bool importTarget = false; while ( s != args.end() ) { if (*s == "WIN32") @@ -49,11 +50,22 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args) ++s; excludeFromAll = true; } + else if(*s == "IMPORT") + { + ++s; + importTarget = true; + } else { break; } } + + if (importTarget) + { + cmTarget* target = this->Makefile->AddNewTarget(cmTarget::EXECUTABLE, exename.c_str(), true); + return true; + } if (s == args.end()) { diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 5a13f60..4174ba6 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -29,7 +29,7 @@ bool cmGetTargetPropertyCommand::InitialPass( const char* targetName = args[1].c_str(); cmTarget *tgt = this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->FindTarget(0,targetName); + ->FindTarget(0, targetName, true); if (tgt) { cmTarget& target = *tgt; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 94cbf36..4f2e6f4 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -625,6 +625,7 @@ void cmGlobalGenerator::Configure() this->LocalGenerators.clear(); this->TargetDependencies.clear(); this->TotalTargets.clear(); + this->ImportedTotalTargets.clear(); this->ProjectToTargetMap.clear(); this->ProjectMap.clear(); @@ -1179,7 +1180,8 @@ cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir) cmTarget* cmGlobalGenerator::FindTarget(const char* project, - const char* name) + const char* name, + bool useImportedTargets) { // if project specific if(project) @@ -1187,7 +1189,8 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project, std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project]; for(unsigned int i = 0; i < gens->size(); ++i) { - cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name); + cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name, + useImportedTargets); if(ret) { return ret; @@ -1197,13 +1200,22 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project, // if all projects/directories else { - std::map<cmStdString,cmTarget *>::iterator i = - this->TotalTargets.find(name); - if (i == this->TotalTargets.end()) + std::map<cmStdString,cmTarget *>::iterator i = + this->TotalTargets.find ( name ); + if ( i != this->TotalTargets.end() ) { - return 0; + return i->second; + } + + if ( useImportedTargets ) + { + std::map<cmStdString,cmTarget *>::iterator importedTarget = + this->ImportedTotalTargets.find ( name ); + if ( importedTarget != this->ImportedTotalTargets.end() ) + { + return importedTarget->second; + } } - return i->second; } return 0; } @@ -1549,12 +1561,12 @@ std::vector<cmTarget *>& cmGlobalGenerator if(emitted.insert(lib->first).second) { cmTarget *target2 = - target.GetMakefile()->FindTarget(lib->first.c_str()); - + target.GetMakefile()->FindTarget(lib->first.c_str(), false); + // search each local generator until a match is found if (!target2) { - target2 = this->FindTarget(0,lib->first.c_str()); + target2 = this->FindTarget(0,lib->first.c_str(), false); } // if a match was found then ... @@ -1575,12 +1587,12 @@ std::vector<cmTarget *>& cmGlobalGenerator // Don't emit the same utility twice for this target. if(emitted.insert(*util).second) { - cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str()); + cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str(), false); // search each local generator until a match is found if (!target2) { - target2 = this->FindTarget(0,util->c_str()); + target2 = this->FindTarget(0,util->c_str(), false); } // if a match was found then ... @@ -1594,3 +1606,14 @@ std::vector<cmTarget *>& cmGlobalGenerator return result; } +void cmGlobalGenerator::AddTarget(cmTargets::value_type &v) +{ + if (v.second.IsImported()) + { + this->ImportedTotalTargets[v.first] = &v.second; + } + else + { + this->TotalTargets[v.first] = &v.second; + } +} diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 15903c4..f19ffb3 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -157,7 +157,7 @@ public: void FindMakeProgram(cmMakefile*); ///! Find a target by name by searching the local generators. - cmTarget* FindTarget(const char* project, const char* name); + cmTarget* FindTarget(const char* project, const char* name, bool useImportedTargets); /** If check to see if the target is linked to by any other target in the project */ @@ -177,9 +177,8 @@ public: configuration. This is valid during generation only. */ cmTargetManifest const& GetTargetManifest() { return this->TargetManifest; } - void AddTarget(cmTargets::value_type &v) { - this->TotalTargets[v.first] = &v.second;}; - + void AddTarget(cmTargets::value_type &v); + /** Support for multiple custom command outputs. */ virtual void CheckMultipleOutputs(cmMakefile* mf, bool verbose); @@ -240,6 +239,7 @@ private: // this is used to improve performance std::map<cmStdString,cmTarget *> TotalTargets; + std::map<cmStdString,cmTarget *> ImportedTotalTargets; std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies; }; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 068cc51..6d4da98 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -641,51 +641,49 @@ cmGlobalUnixMakefileGenerator3 // simple name) if(t->second.GetName() && strlen(t->second.GetName()) && - emitted.insert(t->second.GetName()).second) + emitted.insert(t->second.GetName()).second && + // Handle user targets here. Global targets are handled in + // the local generator on a per-directory basis. + ((t->second.GetType() == cmTarget::EXECUTABLE) || + (t->second.GetType() == cmTarget::STATIC_LIBRARY) || + (t->second.GetType() == cmTarget::SHARED_LIBRARY) || + (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::UTILITY))) { - // Handle user targets here. Global targets are handled in - // the local generator on a per-directory basis. - if((t->second.GetType() == cmTarget::EXECUTABLE) || - (t->second.GetType() == cmTarget::STATIC_LIBRARY) || - (t->second.GetType() == cmTarget::SHARED_LIBRARY) || - (t->second.GetType() == cmTarget::MODULE_LIBRARY) || - (t->second.GetType() == cmTarget::UTILITY)) - { - // Add a rule to build the target by name. - lg->WriteDivider(ruleFileStream); - ruleFileStream - << "# Target rules for targets named " - << t->second.GetName() << "\n\n"; - - // Write the rule. - commands.clear(); - std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); - tmp += "Makefile2"; - commands.push_back(lg->GetRecursiveMakeCall - (tmp.c_str(),t->second.GetName())); - depends.clear(); - depends.push_back("cmake_check_build_system"); - lg->WriteMakeRule(ruleFileStream, - "Build rule for target.", - t->second.GetName(), depends, commands, - true); - - // Add a fast rule to build the target - std::string localName = lg->GetRelativeTargetDirectory(t->second); - std::string makefileName; - makefileName = localName; - makefileName += "/build.make"; - depends.clear(); - commands.clear(); - std::string makeTargetName = localName; - makeTargetName += "/build"; - localName = t->second.GetName(); - localName += "/fast"; - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(), makeTargetName.c_str())); - lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", - localName.c_str(), depends, commands, true); - } + // Add a rule to build the target by name. + lg->WriteDivider(ruleFileStream); + ruleFileStream + << "# Target rules for targets named " + << t->second.GetName() << "\n\n"; + + // Write the rule. + commands.clear(); + std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); + tmp += "Makefile2"; + commands.push_back(lg->GetRecursiveMakeCall + (tmp.c_str(),t->second.GetName())); + depends.clear(); + depends.push_back("cmake_check_build_system"); + lg->WriteMakeRule(ruleFileStream, + "Build rule for target.", + t->second.GetName(), depends, commands, + true); + + // Add a fast rule to build the target + std::string localName = lg->GetRelativeTargetDirectory(t->second); + std::string makefileName; + makefileName = localName; + makefileName += "/build.make"; + depends.clear(); + commands.clear(); + std::string makeTargetName = localName; + makeTargetName += "/build"; + localName = t->second.GetName(); + localName += "/fast"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(), makeTargetName.c_str())); + lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", + localName.c_str(), depends, commands, true); } } } @@ -714,7 +712,13 @@ cmGlobalUnixMakefileGenerator3 cmTargets& targets = lg->GetMakefile()->GetTargets(); for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) { - if (t->second.GetName() && strlen(t->second.GetName())) + if (t->second.GetName() + && strlen(t->second.GetName()) + && ((t->second.GetType() == cmTarget::EXECUTABLE) + || (t->second.GetType() == cmTarget::STATIC_LIBRARY) + || (t->second.GetType() == cmTarget::SHARED_LIBRARY) + || (t->second.GetType() == cmTarget::MODULE_LIBRARY) + || (t->second.GetType() == cmTarget::UTILITY))) { std::string makefileName; // Add a rule to build the target by name. @@ -722,165 +726,158 @@ cmGlobalUnixMakefileGenerator3 makefileName = localName; makefileName += "/build.make"; - if (((t->second.GetType() == cmTarget::EXECUTABLE) || - (t->second.GetType() == cmTarget::STATIC_LIBRARY) || - (t->second.GetType() == cmTarget::SHARED_LIBRARY) || - (t->second.GetType() == cmTarget::MODULE_LIBRARY) || - (t->second.GetType() == cmTarget::UTILITY))) + bool needRequiresStep = + this->NeedRequiresStep(lg,t->second.GetName()); + + lg->WriteDivider(ruleFileStream); + ruleFileStream + << "# Target rules for target " + << localName << "\n\n"; + + commands.clear(); + if (t->second.GetType() != cmTarget::UTILITY) { - bool needRequiresStep = - this->NeedRequiresStep(lg,t->second.GetName()); + makeTargetName = localName; + makeTargetName += "/depend"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); - lg->WriteDivider(ruleFileStream); - ruleFileStream - << "# Target rules for target " - << localName << "\n\n"; - - commands.clear(); - if (t->second.GetType() != cmTarget::UTILITY) + // add requires if we need it for this generator + if (needRequiresStep) { makeTargetName = localName; - makeTargetName += "/depend"; + makeTargetName += "/requires"; commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); - - // add requires if we need it for this generator - if (needRequiresStep) - { - makeTargetName = localName; - makeTargetName += "/requires"; - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); - } + (makefileName.c_str(),makeTargetName.c_str())); } - makeTargetName = localName; - makeTargetName += "/build"; - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); - - // Write the rule. - localName += "/all"; - depends.clear(); + } + makeTargetName = localName; + makeTargetName += "/build"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); + + // Write the rule. + localName += "/all"; + depends.clear(); - std::string progressDir = - lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); - { - cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; - // all target counts - progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " "; - std::vector<int> &progFiles = lg->ProgressFiles[t->first]; - for (std::vector<int>::iterator i = progFiles.begin(); - i != progFiles.end(); ++i) - { - progCmd << " " << *i; - } - commands.push_back(progCmd.str()); - } - progressDir = "Built target "; - progressDir += t->first; - lg->AppendEcho(commands,progressDir.c_str()); - - this->AppendGlobalTargetDepends(depends,t->second); - lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", - localName.c_str(), depends, commands, true); - - // add the all/all dependency - if (!exclude && !t->second.GetPropertyAsBool("EXCLUDE_FROM_ALL")) - { - depends.clear(); - depends.push_back(localName); - commands.clear(); - lg->WriteMakeRule(ruleFileStream, "Include target in all.", - "all", depends, commands, true); - } - - // Write the rule. - commands.clear(); - progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); - + std::string progressDir = + lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); { - // TODO: Convert the total progress count to a make variable. cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; - // # in target + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + // all target counts progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - // - std::set<cmStdString> emitted; - progCmd << " " - << this->GetTargetTotalNumberOfActions(t->second, - emitted); + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " "; + std::vector<int> &progFiles = lg->ProgressFiles[t->first]; + for (std::vector<int>::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) + { + progCmd << " " << *i; + } commands.push_back(progCmd.str()); } - std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); - tmp += "Makefile2"; - commands.push_back(lg->GetRecursiveMakeCall - (tmp.c_str(),localName.c_str())); + progressDir = "Built target "; + progressDir += t->first; + lg->AppendEcho(commands,progressDir.c_str()); + + this->AppendGlobalTargetDepends(depends,t->second); + lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", + localName.c_str(), depends, commands, true); + + // add the all/all dependency + if (!exclude && !t->second.GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 - progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " 0"; - commands.push_back(progCmd.str()); - } - depends.clear(); - depends.push_back("cmake_check_build_system"); - localName = lg->GetRelativeTargetDirectory(t->second); - localName += "/rule"; - lg->WriteMakeRule(ruleFileStream, - "Build rule for subdir invocation for target.", - localName.c_str(), depends, commands, true); - - // Add a target with the canonical name (no prefix, suffix or path). - commands.clear(); depends.clear(); depends.push_back(localName); - lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", - t->second.GetName(), depends, commands, true); - - // Add rules to prepare the target for installation. - if(t->second.NeedRelinkBeforeInstall()) - { - localName = lg->GetRelativeTargetDirectory(t->second); - localName += "/preinstall"; - depends.clear(); - commands.clear(); - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(), localName.c_str())); - lg->WriteMakeRule(ruleFileStream, - "Pre-install relink rule for target.", - localName.c_str(), depends, commands, true); - depends.clear(); - depends.push_back(localName); - commands.clear(); - lg->WriteMakeRule(ruleFileStream, "Prepare target for install.", - "preinstall", depends, commands, true); - } - - // add the clean rule + commands.clear(); + lg->WriteMakeRule(ruleFileStream, "Include target in all.", + "all", depends, commands, true); + } + + // Write the rule. + commands.clear(); + progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + + { + // TODO: Convert the total progress count to a make variable. + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; + // # in target + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + // + std::set<cmStdString> emitted; + progCmd << " " + << this->GetTargetTotalNumberOfActions(t->second, + emitted); + commands.push_back(progCmd.str()); + } + std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); + tmp += "Makefile2"; + commands.push_back(lg->GetRecursiveMakeCall + (tmp.c_str(),localName.c_str())); + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " 0"; + commands.push_back(progCmd.str()); + } + depends.clear(); + depends.push_back("cmake_check_build_system"); + localName = lg->GetRelativeTargetDirectory(t->second); + localName += "/rule"; + lg->WriteMakeRule(ruleFileStream, + "Build rule for subdir invocation for target.", + localName.c_str(), depends, commands, true); + + // Add a target with the canonical name (no prefix, suffix or path). + commands.clear(); + depends.clear(); + depends.push_back(localName); + lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", + t->second.GetName(), depends, commands, true); + + // Add rules to prepare the target for installation. + if(t->second.NeedRelinkBeforeInstall()) + { localName = lg->GetRelativeTargetDirectory(t->second); - makeTargetName = localName; - makeTargetName += "/clean"; + localName += "/preinstall"; depends.clear(); commands.clear(); commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(), makeTargetName.c_str())); - lg->WriteMakeRule(ruleFileStream, "clean rule for target.", - makeTargetName.c_str(), depends, commands, true); + (makefileName.c_str(), localName.c_str())); + lg->WriteMakeRule(ruleFileStream, + "Pre-install relink rule for target.", + localName.c_str(), depends, commands, true); + depends.clear(); + depends.push_back(localName); commands.clear(); - depends.push_back(makeTargetName); - lg->WriteMakeRule(ruleFileStream, "clean rule for target.", - "clean", depends, commands, true); + lg->WriteMakeRule(ruleFileStream, "Prepare target for install.", + "preinstall", depends, commands, true); } + + // add the clean rule + localName = lg->GetRelativeTargetDirectory(t->second); + makeTargetName = localName; + makeTargetName += "/clean"; + depends.clear(); + commands.clear(); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(), makeTargetName.c_str())); + lg->WriteMakeRule(ruleFileStream, "clean rule for target.", + makeTargetName.c_str(), depends, commands, true); + commands.clear(); + depends.push_back(makeTargetName); + lg->WriteMakeRule(ruleFileStream, "clean rule for target.", + "clean", depends, commands, true); } } } @@ -1060,12 +1057,12 @@ cmGlobalUnixMakefileGenerator3 // first check the same dir as the current target lg3 = static_cast<cmLocalUnixMakefileGenerator3 *> (target.GetMakefile()->GetLocalGenerator()); - result = target.GetMakefile()->FindTarget(name); + result = target.GetMakefile()->FindTarget(name, false); // search each local generator until a match is found if (!result) { - result = this->FindTarget(0,name); + result = this->FindTarget(0, name, false); if (result) { lg3 = static_cast<cmLocalUnixMakefileGenerator3 *> diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 3829b3e..f06c77d 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -401,7 +401,7 @@ void cmGlobalVisualStudio6Generator::WriteProject(std::ostream& fout, if(j->first != dspname) { // is the library part of this DSW ? If so add dependency - if(this->FindTarget(0, j->first.c_str())) + if(this->FindTarget(0, j->first.c_str()), false) { fout << "Begin Project Dependency\n"; fout << "Project_Dep_Name " << j->first.c_str() << "\n"; diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index dd6ea9f..523c3e0 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -333,7 +333,9 @@ cmGlobalVisualStudio71Generator if(j->first != dspname) { // is the library part of this SLN ? If so add dependency - if(this->FindTarget(this->CurrentProject.c_str(), j->first.c_str())) + if(this->FindTarget(this->CurrentProject.c_str(), + j->first.c_str()), + false) { fout << "\t\t{" << this->GetGUID(j->first.c_str()) << "} = {" << this->GetGUID(j->first.c_str()) << "}\n"; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 67fd7a3..2877b7a 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -588,7 +588,9 @@ cmGlobalVisualStudio7Generator if(j->first != dspname) { // is the library part of this SLN ? If so add dependency - if(this->FindTarget(this->CurrentProject.c_str(), j->first.c_str())) + if(this->FindTarget(this->CurrentProject.c_str(), + j->first.c_str()), + false) { std::string guid = this->GetGUID(j->first.c_str()); if(guid.size() == 0) diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 694c2db..2c2325b 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -94,7 +94,7 @@ void cmGlobalVisualStudio8Generator::Generate() mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false, no_working_directory, no_depends, noCommandLines); - cmTarget* tgt = mf->FindTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET); + cmTarget* tgt = mf->FindTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false); if(!tgt) { cmSystemTools::Error("Error adding target " diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index c5b291a..658516c 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -104,7 +104,7 @@ cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget(cmTarget& target) target.GetUtilities().begin(); ui != target.GetUtilities().end(); ++ui) { - if(cmTarget* depTarget = this->FindTarget(0, ui->c_str())) + if(cmTarget* depTarget = this->FindTarget(0, ui->c_str(), false)) { if(depTarget->GetType() == cmTarget::STATIC_LIBRARY || depTarget->GetType() == cmTarget::SHARED_LIBRARY || @@ -149,7 +149,7 @@ cmGlobalVisualStudioGenerator::CreateUtilityDependTarget(cmTarget& target) this->CreateGUID(altNameStr.c_str()); // The intermediate target should depend on the original target. - if(cmTarget* alt = this->FindTarget(0, altNameStr.c_str())) + if(cmTarget* alt = this->FindTarget(0, altNameStr.c_str(), false)) { alt->AddUtility(target.GetName()); } @@ -205,7 +205,7 @@ cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target, { // 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)) + if(cmTarget* depTarget = this->FindTarget(0, name, false)) { // Check for an alternative name created by FixUtilityDepends. if(const char* altName = diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4b42796..6662236 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -272,7 +272,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, mf->AddUtilityCommand("ALL_BUILD", true, no_depends, no_working_directory, "echo", "Build all projects"); - cmTarget* allbuild = mf->FindTarget("ALL_BUILD"); + cmTarget* allbuild = mf->FindTarget("ALL_BUILD", false); // Add XCODE depend helper std::string dir = mf->GetCurrentOutputDirectory(); @@ -1035,8 +1035,7 @@ void cmGlobalXCodeGenerator cc.GetDepends().begin(); d != cc.GetDepends().end(); ++d) { - if(!this->FindTarget(this->CurrentProject.c_str(), - d->c_str())) + if(!this->FindTarget(this->CurrentProject.c_str(), d->c_str(), false)) { // if the depend is not a target but // is a full path then use it, if not then @@ -1860,7 +1859,7 @@ void cmGlobalXCodeGenerator { // Add this dependency. cmTarget* t = this->FindTarget(this->CurrentProject.c_str(), - lib->first.c_str()); + lib->first.c_str(), false); cmXCodeObject* dptarget = this->FindXCodeTarget(t); if(dptarget) { @@ -1876,7 +1875,7 @@ void cmGlobalXCodeGenerator i != cmtarget->GetUtilities().end(); ++i) { cmTarget* t = this->FindTarget(this->CurrentProject.c_str(), - i->c_str()); + i->c_str(), false); // if the target is in this project then make target depend // on it. It may not be in this project if this is a sub // project from the top. diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx index d4a74ba..53da366 100644 --- a/Source/cmIncludeExternalMSProjectCommand.cxx +++ b/Source/cmIncludeExternalMSProjectCommand.cxx @@ -50,10 +50,8 @@ bool cmIncludeExternalMSProjectCommand cmSystemTools::ConvertToUnixSlashes(path); // Create a target instance for this utility. - cmTarget target; - target.SetType(cmTarget::UTILITY, utility_name.c_str()); - target.SetProperty("EXCLUDE_FROM_ALL","FALSE"); - target.SetMakefile(this->Makefile); + cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY, utility_name.c_str()); + target->SetProperty("EXCLUDE_FROM_ALL","FALSE"); std::vector<std::string> no_outputs; cmCustomCommandLines commandLines; cmCustomCommandLine commandLine; @@ -61,13 +59,7 @@ bool cmIncludeExternalMSProjectCommand commandLine.push_back(path); commandLines.push_back(commandLine); cmCustomCommand cc(no_outputs, depends, commandLines, 0, 0); - target.GetPostBuildCommands().push_back(cc); - - // Add the target to the set of targets. - cmTargets::iterator it = - this->Makefile->GetTargets() - .insert(cmTargets::value_type(utility_name.c_str(),target)).first; - this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->AddTarget(*it); + target->GetPostBuildCommands().push_back(cc); } #endif return true; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 5244b9f..a15b656 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -252,7 +252,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) else if(doing_targets) { // Lookup this target in the current directory. - if(cmTarget* target = this->Makefile->FindTarget(args[i].c_str())) + if(cmTarget* target = this->Makefile->FindTarget(args[i].c_str(), false)) { // Found the target. Check its type. if(target->GetType() != cmTarget::EXECUTABLE && diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index a3d2dbb..45e715f 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -376,7 +376,7 @@ void cmInstallTargetGenerator { if(cmTarget* tgt = this->Target->GetMakefile()-> GetLocalGenerator()->GetGlobalGenerator()-> - FindTarget(0, lib.c_str())) + FindTarget(0, lib.c_str(), false)) { if(tgt->GetType() == cmTarget::SHARED_LIBRARY) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 110c60f..052663a 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -148,8 +148,7 @@ void cmLocalGenerator::TraceDependencies() if ((t->second.GetType() != cmTarget::INSTALL_FILES) && (t->second.GetType() != cmTarget::INSTALL_PROGRAMS) && (t->second.GetType() != cmTarget::INSTALL_DIRECTORY) - && (strncmp(t->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0) - && (t->second.GetPropertyAsBool("IMPORTED") == false)) + && (strncmp(t->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0)) { std::string projectFilename; if (this->IsMakefileGenerator == false) // only use of this variable @@ -1733,7 +1732,7 @@ void cmLocalGenerator (j->second == cmTarget::GENERAL || j->second == linkType)) { // Compute the proper name to use to link this library. - cmTarget* tgt = this->GlobalGenerator->FindTarget(0, lib.c_str()); + cmTarget* tgt = this->GlobalGenerator->FindTarget(0, lib.c_str(), false); bool impexe = (tgt && tgt->GetType() == cmTarget::EXECUTABLE && tgt->GetPropertyAsBool("ENABLE_EXPORTS")); @@ -1963,7 +1962,7 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, } // Look for a CMake target with the given name. - if(cmTarget* target = this->GlobalGenerator->FindTarget(0, name.c_str())) + if(cmTarget* target = this->GlobalGenerator->FindTarget(0,name.c_str(),false)) { // make sure it is not just a coincidence that the target name // found is part of the inName @@ -2029,8 +2028,8 @@ std::string cmLocalGenerator::GetRealLocation(const char* inName, { std::string outName=inName; // Look for a CMake target with the given name. - cmTarget* target = this->GlobalGenerator->FindTarget(0, inName); - if ((target!=0) && (target->GetType()==cmTarget::EXECUTABLE)) + cmTarget* target = this->GlobalGenerator->FindTarget(0, inName, true); + if ((target != 0) && (target->GetType() == cmTarget::EXECUTABLE)) { outName = target->GetLocation( config ); } diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 252314e..08289ba 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -114,7 +114,6 @@ void cmLocalUnixMakefileGenerator3::Generate() if (tg) { this->TargetGenerators.push_back(tg); -// t->second.TraceVSDependencies(empty, this->Makefile); tg->WriteRuleFiles(); } } diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 20b0d57..b877cb9 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1051,7 +1051,8 @@ void cmLocalVisualStudio6Generator // Compute the proper name to use to link this library. std::string lib; std::string libDebug; - cmTarget* tgt = this->GlobalGenerator->FindTarget(0, j->first.c_str()); + cmTarget* tgt = this->GlobalGenerator->FindTarget(0, j->first.c_str(), + false); if(tgt) { lib = cmSystemTools::GetFilenameWithoutExtension diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f126d0e..064e153 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -825,12 +825,10 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, bool escapeOldStyle, const char* comment) { // Create a target instance for this utility. - cmTarget target; - target.SetMakefile(this); - target.SetType(cmTarget::UTILITY, utilityName); + cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName, false); if (excludeFromAll) { - target.SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } if(!comment) { @@ -850,7 +848,7 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, commandLines, comment, workingDirectory, no_replace, escapeOldStyle); - target.GetSourceLists().push_back(force); + target->GetSourceLists().push_back(force); // The output is not actually created so mark it symbolic. if(cmSourceFile* sf = this->GetSource(force.c_str())) @@ -862,11 +860,6 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, cmSystemTools::Error("Could not get source file entry for ", force.c_str()); } - - // Add the target to the set of targets. - cmTargets::iterator it = - this->Targets.insert(cmTargets::value_type(utilityName,target)).first; - this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it); } void cmMakefile::AddDefineFlag(const char* flag) @@ -940,7 +933,7 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target, if ( i != this->Targets.end()) { cmTarget* tgt = - this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0, lib); + this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0, lib, false); if(tgt) { bool allowModules = true; @@ -1343,53 +1336,64 @@ void cmMakefile::AddLibrary(const char* lname, int shared, const std::vector<std::string> &srcs, bool excludeFromAll) { - cmTarget target; + cmTarget* target=0; switch (shared) { case 0: - target.SetType(cmTarget::STATIC_LIBRARY, lname); + target=this->AddNewTarget(cmTarget::STATIC_LIBRARY, lname, false); break; case 1: - target.SetType(cmTarget::SHARED_LIBRARY, lname); + target=this->AddNewTarget(cmTarget::SHARED_LIBRARY, lname, false); break; case 2: - target.SetType(cmTarget::MODULE_LIBRARY, lname); + target=this->AddNewTarget(cmTarget::MODULE_LIBRARY, lname, false); break; default: - target.SetType(cmTarget::STATIC_LIBRARY, lname); + target=this->AddNewTarget(cmTarget::STATIC_LIBRARY, lname, false); } - target.SetMakefile(this); // Clear its dependencies. Otherwise, dependencies might persist // over changes in CMakeLists.txt, making the information stale and // hence useless. - target.ClearDependencyInformation( *this, lname ); + target->ClearDependencyInformation( *this, lname ); if(excludeFromAll) { - target.SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } - target.GetSourceLists() = srcs; - this->AddGlobalLinkInformation(lname, target); - cmTargets::iterator it = - this->Targets.insert(cmTargets::value_type(lname,target)).first; - this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it); + target->GetSourceLists() = srcs; + this->AddGlobalLinkInformation(lname, *target); } cmTarget* cmMakefile::AddExecutable(const char *exeName, const std::vector<std::string> &srcs, bool excludeFromAll) { - cmTarget target; - target.SetType(cmTarget::EXECUTABLE, exeName); - target.SetMakefile(this); + cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName, false); if(excludeFromAll) { - target.SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } - target.GetSourceLists() = srcs; - this->AddGlobalLinkInformation(exeName, target); - cmTargets::iterator it = - this->Targets.insert(cmTargets::value_type(exeName,target)).first; + target->GetSourceLists() = srcs; + this->AddGlobalLinkInformation(exeName, *target); + return target; +} + + +cmTarget* cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name, bool isImported) +{ + cmTargets::iterator it; + cmTarget target; + target.SetType(type, name); + target.SetMakefile(this); + if (isImported) + { + target.MarkAsImported(); + it=this->ImportedTargets.insert(cmTargets::value_type(target.GetName(), target)).first; + } + else + { + it=this->Targets.insert(cmTargets::value_type(target.GetName(), target)).first; + } this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it); return &it->second; } @@ -2709,7 +2713,7 @@ const char *cmMakefile::GetProperty(const char* prop, return this->GetCMakeInstance()->GetProperty(prop,scope); } - return retVal; + return retVal; } bool cmMakefile::GetPropertyAsBool(const char* prop) @@ -2718,16 +2722,26 @@ bool cmMakefile::GetPropertyAsBool(const char* prop) } -cmTarget* cmMakefile::FindTarget(const char* name) +cmTarget* cmMakefile::FindTarget(const char* name, bool useImportedTargets) { cmTargets& tgts = this->GetTargets(); - - cmTargets::iterator i = tgts.find(name); - if (i == tgts.end()) + + cmTargets::iterator i = tgts.find ( name ); + if ( i != tgts.end() ) { - return 0; + return &i->second; } - return &i->second; + + if (useImportedTargets) + { + cmTargets::iterator impTarget = this->ImportedTargets.find(name); + if (impTarget != this->ImportedTargets.end()) + { + return &impTarget->second; + } + } + + return 0; } cmTest* cmMakefile::CreateTest(const char* testName) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 8f4d0ee..0c4341a 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -167,6 +167,8 @@ public: void AddDefineFlag(const char* definition); void RemoveDefineFlag(const char* definition); + cmTarget* AddNewTarget(cmTarget::TargetType type, const char* name, bool isImported); + /** * Add an executable to the build. */ @@ -416,8 +418,9 @@ public: * Get the list of targets */ cmTargets &GetTargets() { return this->Targets; } + const cmTargets &GetImportedTargets() const { return this->ImportedTargets; } - cmTarget* FindTarget(const char* name); + cmTarget* FindTarget(const char* name, bool useImportedTargets); /** @@ -741,6 +744,7 @@ protected: // libraries, classes, and executables cmTargets Targets; + cmTargets ImportedTargets; std::vector<cmSourceFile*> SourceFiles; // Tests diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 8eec8c2..abef8a8 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1194,7 +1194,7 @@ void cmMakefileTargetGenerator { // Depend on other CMake targets. if(cmTarget* tgt = - this->GlobalGenerator->FindTarget(0, lib->first.c_str())) + this->GlobalGenerator->FindTarget(0, lib->first.c_str(), false)) { if(const char* location = tgt->GetLocation(this->LocalGenerator->ConfigurationName.c_str())) diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index 342989d..4fb2fb9 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -96,7 +96,7 @@ bool cmSetTargetPropertiesCommand cmMakefile *mf) { cmTarget* target = - mf->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, tname); + mf->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, tname, true); if ( target) { // now loop through all the props and set them diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5d59755..f6f23e0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -38,7 +38,7 @@ cmTarget::cmTarget() this->LinkDirectoriesComputed = false; this->HaveInstallRule = false; this->DLLPlatform = false; - + this->IsImportedTarget = false; } // define properties @@ -90,7 +90,7 @@ void cmTarget::DefineProperties(cmake *cm) cm->DefineProperty ("EchoString", cmProperty::TARGET, - "A message to be displayed when the target it built.", + "A message to be displayed when the target is built.", "A message to display on some generaters (such as makefiles) when " "the target is built."); @@ -424,8 +424,8 @@ cmTarget { std::string command = *cit->begin(); // see if we can find a target with this name - cmTarget* t = this->Makefile->GetLocalGenerator()-> - GetGlobalGenerator()->FindTarget ( 0, command.c_str() ); + cmTarget* t = this->Makefile->GetLocalGenerator()-> + GetGlobalGenerator()->FindTarget(0, command.c_str(), false); if ( ( t ) && ( t->GetType() ==cmTarget::EXECUTABLE ) ) { this->AddUtility ( command.c_str() ); @@ -577,7 +577,7 @@ void cmTarget::TraceVSDependencies(std::string projFile, const std::string& currentCommand = (*it)[0]; // see if we can find a target with this name cmTarget* t = this->Makefile->GetLocalGenerator()-> - GetGlobalGenerator()->FindTarget(0, currentCommand.c_str()); + GetGlobalGenerator()->FindTarget(0, currentCommand.c_str(), false); if (( t) && (t->GetType()==cmTarget::EXECUTABLE)) { automaticTargetDepends.push_back(currentCommand); @@ -600,7 +600,7 @@ void cmTarget::TraceVSDependencies(std::string projFile, bool isUtility = false; // see if we can find a target with this name cmTarget* t = this->Makefile->GetLocalGenerator()-> - GetGlobalGenerator()->FindTarget(0, dep.c_str()); + GetGlobalGenerator()->FindTarget(0, dep.c_str(), false); if(t) { // if we find the target and the dep was given as a full @@ -783,7 +783,7 @@ const std::vector<std::string>& cmTarget::GetLinkDirectories() this->Makefile->GetLocalGenerator()->GetGlobalGenerator()) { tgt = (this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->FindTarget(0, lib.c_str())); + ->FindTarget(0, lib.c_str(), false)); } if(tgt) { @@ -1220,8 +1220,32 @@ void cmTarget::SetProperty(const char* prop, const char* value) this->Properties.SetProperty(prop, value, cmProperty::TARGET); } +void cmTarget::MarkAsImported() +{ + this->IsImportedTarget = true; +} + const char* cmTarget::GetDirectory(const char* config, bool implib) { + if (this->IsImported()) + { + return this->ImportedGetDirectory(config, implib); + } + else + { + return this->NormalGetDirectory(config, implib); + } +} + +const char* cmTarget::ImportedGetDirectory(const char* config, bool implib) +{ + const char* location=this->GetLocation(config); + std::string directory=cmSystemTools::GetFilenamePath(location); + return directory.c_str(); +} + +const char* cmTarget::NormalGetDirectory(const char* config, bool implib) +{ if(config && *config) { this->Directory = this->GetOutputDir(implib); @@ -1238,6 +1262,34 @@ const char* cmTarget::GetDirectory(const char* config, bool implib) const char* cmTarget::GetLocation(const char* config) { + if (this->IsImported()) + { + return this->ImportedGetLocation(config); + } + else + { + return this->NormalGetLocation(config); + } +} + +const char* cmTarget::ImportedGetLocation(const char* config) +{ + if ((config) && (strlen(config))) + { + std::string propertyName=config; + propertyName+="_LOCATION"; + const char* configLocation=this->GetProperty(propertyName.c_str()); + if ((configLocation) && (strlen(configLocation))) + { + return configLocation; + } + } + + return this->GetProperty("LOCATION"); +} + +const char* cmTarget::NormalGetLocation(const char* config) +{ this->Location = this->GetDirectory(); if(!this->Location.empty()) { @@ -1283,6 +1335,11 @@ const char *cmTarget::GetProperty(const char* prop) void cmTarget::ComputeObjectFiles() { + if (this->IsImported()) + { + return; + } + // Force the SourceFiles vector to be populated this->GenerateSourceFilesFromSourceLists(*this->Makefile); std::vector<std::string> dirs; @@ -1336,33 +1393,43 @@ const char *cmTarget::GetProperty(const char* prop, return 0; } - // watch for special "computed" properties that are dependent on other - // properties or variables, always recompute them - if (!strcmp(prop,"LOCATION")) - { - // Set the LOCATION property of the target. Note that this cannot take - // into account the per-configuration name of the target because the - // configuration type may not be known at CMake time. We should - // deprecate this feature and instead support transforming an executable - // target name given as the command part of custom commands into the - // proper path at build time. Alternatively we could put environment - // variable settings in all custom commands that hold the name of the - // target for each configuration and then give a reference to the - // variable in the location. - this->SetProperty("LOCATION", this->GetLocation(0)); - } - - // Per-configuration location can be computed. - int len = static_cast<int>(strlen(prop)); - if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0) - { - std::string configName(prop, len-9); - this->SetProperty(prop, this->GetLocation(configName.c_str())); - } - - if(strcmp(prop, "OBJECT_FILES") == 0) + // don't use GetLocation() for imported targets, because there this + // calls GetProperty() to get the location... + if (!this->IsImported()) + { + // watch for special "computed" properties that are dependent on other + // properties or variables, always recompute them + if (!strcmp(prop,"LOCATION")) + { + // Set the LOCATION property of the target. Note that this cannot take + // into account the per-configuration name of the target because the + // configuration type may not be known at CMake time. We should + // deprecate this feature and instead support transforming an executable + // target name given as the command part of custom commands into the + // proper path at build time. Alternatively we could put environment + // variable settings in all custom commands that hold the name of the + // target for each configuration and then give a reference to the + // variable in the location. + this->SetProperty("LOCATION", this->GetLocation(0)); + } + + // Per-configuration location can be computed. + int len = static_cast<int>(strlen(prop)); + if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0) + { + std::string configName(prop, len-9); + this->SetProperty(prop, this->GetLocation(configName.c_str())); + } + + if(strcmp(prop, "OBJECT_FILES") == 0) + { + this->ComputeObjectFiles(); + } + } + + if (strcmp(prop,"IMPORTED") == 0) { - this->ComputeObjectFiles(); + return this->IsImported()?"TRUE":"FALSE"; } // the type property returns what type the target is @@ -1607,13 +1674,48 @@ std::string cmTarget::GetFullNameInternal(TargetType type, const char* config, return prefix+base+suffix; } -//---------------------------------------------------------------------------- void cmTarget::GetFullNameInternal(TargetType type, - const char* config, - bool implib, - std::string& outPrefix, - std::string& outBase, - std::string& outSuffix) + const char* config, + bool implib, + std::string& outPrefix, + std::string& outBase, + std::string& outSuffix) +{ + if (this->IsImported()) + { + this->ImportedGetFullNameInternal(type, config, implib, + outPrefix, outBase, outSuffix); + } + else + { + this->NormalGetFullNameInternal(type, config, implib, + outPrefix, outBase, outSuffix); + } +} + +void cmTarget::ImportedGetFullNameInternal(TargetType type, + const char* config, + bool implib, + std::string& outPrefix, + std::string& outBase, + std::string& outSuffix) +{ + // find the basename, suffix and prefix from getLocation() + // implib ? + std::string location=this->GetLocation(config); + outBase=cmSystemTools::GetFilenameWithoutExtension(location); + outSuffix = cmSystemTools::GetFilenameExtension(location); + outPrefix.clear(); +} + + +//---------------------------------------------------------------------------- +void cmTarget::NormalGetFullNameInternal(TargetType type, + const char* config, + bool implib, + std::string& outPrefix, + std::string& outBase, + std::string& outSuffix) { // Use just the target name for non-main target types. if(type != cmTarget::STATIC_LIBRARY && diff --git a/Source/cmTarget.h b/Source/cmTarget.h index aa2d4db..4161b35 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -44,7 +44,7 @@ public: /** * Return the type of target. */ - TargetType GetType() + TargetType GetType() const { return this->TargetTypeValue; } @@ -54,6 +54,8 @@ public: */ void SetType(TargetType f, const char* name); + void MarkAsImported(); + ///! Set/Get the name of the target const char* GetName() const {return this->Name.c_str();} @@ -161,6 +163,8 @@ public: const char *GetProperty(const char *prop); const char *GetProperty(const char *prop, cmProperty::ScopeType scope); bool GetPropertyAsBool(const char *prop); + + bool IsImported() const {return this->IsImportedTarget;} /** Get the directory in which this target will be built. If the configuration name is given then the generator will add its @@ -327,6 +331,7 @@ private: void GetFullNameInternal(TargetType type, const char* config, bool implib, std::string& outPrefix, std::string& outBase, std::string& outSuffix); + void GetLibraryNamesInternal(std::string& name, std::string& soName, std::string& realName, @@ -348,6 +353,19 @@ private: // Get the full path to the target output directory. const char* GetOutputDir(bool implib); + const char* ImportedGetLocation(const char* config); + const char* NormalGetLocation(const char* config); + + void NormalGetFullNameInternal(TargetType type, const char* config, bool implib, + std::string& outPrefix, std::string& outBase, + std::string& outSuffix); + void ImportedGetFullNameInternal(TargetType type, const char* config, bool implib, + std::string& outPrefix, std::string& outBase, + std::string& outSuffix); + + const char* ImportedGetDirectory(const char* config, bool implib); + const char* NormalGetDirectory(const char* config, bool implib); + private: std::string Name; std::vector<cmCustomCommand> PreBuildCommands; @@ -376,6 +394,7 @@ private: cmPropertyMap Properties; LinkLibraryVectorType OriginalLinkLibraries; bool DLLPlatform; + bool IsImportedTarget; // The cmMakefile instance that owns this target. This should // always be set. |