From 4878c009057cf410fff98d8450e1e7cd2b3072ae Mon Sep 17 00:00:00 2001 From: Alexander Neundorf Date: Tue, 22 May 2007 10:24:59 -0400 Subject: [PATCH] ENH: add the IMPORT keyword to ADD_EXECUTABLE(), which generates an "imported" executable target. This can then be used e.g. with ADD_CUSTOM_COMMAND() to generate stuff. It adds a second container for "imported" targets, and FindTarget() now takes an additional argument bool useImportedTargets to specify whether you also want to search in the imported targets or only in the "normal" targets. Alex --- Source/cmAddDependenciesCommand.cxx | 2 +- Source/cmAddExecutableCommand.cxx | 12 + Source/cmGetTargetPropertyCommand.cxx | 2 +- Source/cmGlobalGenerator.cxx | 47 ++- Source/cmGlobalGenerator.h | 8 +- Source/cmGlobalUnixMakefileGenerator3.cxx | 371 +++++++++---------- Source/cmGlobalVisualStudio6Generator.cxx | 2 +- Source/cmGlobalVisualStudio71Generator.cxx | 4 +- Source/cmGlobalVisualStudio7Generator.cxx | 4 +- Source/cmGlobalVisualStudio8Generator.cxx | 2 +- Source/cmGlobalVisualStudioGenerator.cxx | 6 +- Source/cmGlobalXCodeGenerator.cxx | 9 +- Source/cmIncludeExternalMSProjectCommand.cxx | 14 +- Source/cmInstallCommand.cxx | 2 +- Source/cmInstallTargetGenerator.cxx | 2 +- Source/cmLocalGenerator.cxx | 11 +- Source/cmLocalUnixMakefileGenerator3.cxx | 1 - Source/cmLocalVisualStudio6Generator.cxx | 3 +- Source/cmMakefile.cxx | 92 +++-- Source/cmMakefile.h | 6 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmSetTargetPropertiesCommand.cxx | 2 +- Source/cmTarget.cxx | 180 +++++++-- Source/cmTarget.h | 21 +- 24 files changed, 485 insertions(+), 320 deletions(-) diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index 874c81695e..1b2f8c6483 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::const_iterator s = args.begin(); diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index e791a82924..ad2044c5ed 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -32,6 +32,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector 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 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 5a13f60ab8..4174ba6dae 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 94cbf3619c..4f2e6f4b86 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* 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::iterator i = - this->TotalTargets.find(name); - if (i == this->TotalTargets.end()) + std::map::iterator i = + this->TotalTargets.find ( name ); + if ( i != this->TotalTargets.end() ) { - return 0; + return i->second; + } + + if ( useImportedTargets ) + { + std::map::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& 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& 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& 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 15903c42b1..f19ffb3ebc 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 TotalTargets; + std::map ImportedTotalTargets; std::map > TargetDependencies; }; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 068cc517bd..6d4da98ac2 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"; + bool needRequiresStep = + this->NeedRequiresStep(lg,t->second.GetName()); - commands.clear(); - if (t->second.GetType() != cmTarget::UTILITY) + lg->WriteDivider(ruleFileStream); + ruleFileStream + << "# Target rules for target " + << localName << "\n\n"; + + commands.clear(); + if (t->second.GetType() != cmTarget::UTILITY) + { + makeTargetName = localName; + makeTargetName += "/depend"; + 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 += "/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 &progFiles = lg->ProgressFiles[t->first]; - for (std::vector::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(); - - { - // 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 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())); + std::string progressDir = + lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); { cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + // all target counts progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " 0"; + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " "; + std::vector &progFiles = lg->ProgressFiles[t->first]; + for (std::vector::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) + { + progCmd << " " << *i; + } 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(); + 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); - 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 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 (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 diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 3829b3e090..f06c77d8de 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 dd6ea9f046..523c3e0d58 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 67fd7a3a12..2877b7acbb 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 694c2db9dc..2c2325be75 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 c5b291a590..658516c3e7 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 4b42796ba9..6662236655 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 d4a74ba1cf..53da366e05 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 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 5244b9f9cd..a15b656af7 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -252,7 +252,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector 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 a3d2dbbd6b..45e715f6f6 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 110c60f55b..052663a741 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 252314e46e..08289baf87 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 20b0d5702c..b877cb9f62 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 f126d0e68f..064e15388e 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 &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 &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 8f4d0ee89a..0c4341ad07 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 SourceFiles; // Tests diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 8eec8c2e69..abef8a8286 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 342989d078..4fb2fb94d4 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 5d59755d3e..f6f23e0033 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& 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,7 +1220,31 @@ 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) { @@ -1237,6 +1261,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 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")) + // 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(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) { - // 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(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(); + 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 aa2d4db9e3..4161b35487 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 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.