diff options
Diffstat (limited to 'Source/cmMakefileTargetGenerator.cxx')
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 322 |
1 files changed, 178 insertions, 144 deletions
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a3a832b..3d02d6a 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmMakefileTargetGenerator.h" +#include "cmGeneratorTarget.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmGlobalUnixMakefileGenerator3.h" @@ -27,6 +28,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) + : OSXBundleGenerator(0) + , MacOSXContentGenerator(0) { this->BuildFileStream = 0; this->InfoFileStream = 0; @@ -42,12 +45,19 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) this->GlobalGenerator = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()); + this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target); cmake* cm = this->GlobalGenerator->GetCMakeInstance(); this->NoRuleMessages = false; if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES")) { this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); } + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); +} + +cmMakefileTargetGenerator::~cmMakefileTargetGenerator() +{ + delete MacOSXContentGenerator; } cmMakefileTargetGenerator * @@ -63,6 +73,7 @@ cmMakefileTargetGenerator::New(cmTarget *tgt) case cmTarget::STATIC_LIBRARY: case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + case cmTarget::OBJECT_LIBRARY: result = new cmMakefileLibraryTargetGenerator(tgt); break; case cmTarget::UTILITY: @@ -131,60 +142,48 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // First generate the object rule files. Save a list of all object // files for this target. - const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles(); - for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); - source != sources.end(); ++source) + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->CustomCommands.begin(); + si != this->GeneratorTarget->CustomCommands.end(); ++si) { - cmTarget::SourceFileFlags tsFlags = - this->Target->GetTargetSourceFileFlags(*source); - if(cmCustomCommand* cc = (*source)->GetCustomCommand()) - { - this->GenerateCustomRuleFile(*cc); - if (clean) - { - const std::vector<std::string>& outputs = cc->GetOutputs(); - for(std::vector<std::string>::const_iterator o = outputs.begin(); - o != outputs.end(); ++o) - { - this->CleanFiles.push_back - (this->Convert(o->c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED)); - } - } - } - else if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + cmCustomCommand const* cc = (*si)->GetCustomCommand(); + this->GenerateCustomRuleFile(*cc); + if (clean) { - this->WriteMacOSXContentRules(*(*source), tsFlags.MacFolder); - } - else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY")) - { - if(!this->GlobalGenerator->IgnoreFile - ((*source)->GetExtension().c_str())) - { - // Generate this object file's rule file. - this->WriteObjectRuleFiles(*(*source)); - } - else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT")) - { - // This is an external object file. Just add it. - this->ExternalObjects.push_back((*source)->GetFullPath()); - } - else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF") - { - this->ModuleDefinitionFile = (*source)->GetFullPath(); - } - else + const std::vector<std::string>& outputs = cc->GetOutputs(); + for(std::vector<std::string>::const_iterator o = outputs.begin(); + o != outputs.end(); ++o) { - // We only get here if a source file is not an external object - // and has an extension that is listed as an ignored file type - // for this language. No message or diagnosis should be - // given. + this->CleanFiles.push_back + (this->Convert(o->c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::UNCHANGED)); } } } -} + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->ExternalObjects.begin(); + si != this->GeneratorTarget->ExternalObjects.end(); ++si) + { + this->ExternalObjects.push_back((*si)->GetFullPath()); + } + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->ObjectSources.begin(); + si != this->GeneratorTarget->ObjectSources.end(); ++si) + { + // Generate this object file's rule file. + this->WriteObjectRuleFiles(**si); + } + // Add object library contents as external objects. + this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects); +} //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::WriteCommonCodeRules() @@ -257,13 +256,10 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) std::string flags; const char *lang = l.c_str(); - bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || - (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); - // Add language feature flags. this->AddFeatureFlags(flags, lang); - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, lang, this->ConfigName); // Fortran-specific flags computed for this target. @@ -272,8 +268,7 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) this->AddFortranFlags(flags); } - // Add shared-library flags if needed. - this->LocalGenerator->AddSharedFlags(flags, lang, shared); + this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang); // Add include directory flags. this->AddIncludeFlags(flags, lang); @@ -297,28 +292,26 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); if (i == this->DefinesByLanguage.end()) { - std::string defines; + std::set<std::string> defines; const char *lang = l.c_str(); // Add the export symbol definition for shared library objects. if(const char* exportMacro = this->Target->GetExportMacro()) { - this->LocalGenerator->AppendDefines(defines, exportMacro, lang); + this->LocalGenerator->AppendDefines(defines, exportMacro); } // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); + (defines, this->GeneratorTarget->GetCompileDefinitions()); + this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty(defPropName.c_str()), lang); + (defines, this->GeneratorTarget->GetCompileDefinitions( + this->LocalGenerator->ConfigurationName.c_str())); + + std::string definesString; + this->LocalGenerator->JoinDefines(defines, definesString, lang); - ByLanguageMap::value_type entry(l, defines); + ByLanguageMap::value_type entry(l, definesString); i = this->DefinesByLanguage.insert(entry).first; } return i->second; @@ -359,28 +352,20 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() } } + //---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, - const char* pkgloc) +void +cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator() + (cmSourceFile& source, const char* pkgloc) { // Skip OS X content when not building a Framework or Bundle. - if(this->MacContentDirectory.empty()) + if(this->Generator->MacContentDirectory.empty()) { return; } - // Construct the full path to the content subdirectory. - std::string macdir = this->MacContentDirectory; - macdir += pkgloc; - cmSystemTools::MakeDirectory(macdir.c_str()); - - // Record use of this content location. Only the first level - // directory is needed. - { - std::string loc = pkgloc; - loc = loc.substr(0, loc.find('/')); - this->MacContentFolders.insert(loc); - } + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); // Get the input file location. std::string input = source.GetFullPath(); @@ -389,9 +374,11 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, std::string output = macdir; output += "/"; output += cmSystemTools::GetFilenameName(input); - this->CleanFiles.push_back(this->Convert(output.c_str(), - cmLocalGenerator::START_OUTPUT)); - output = this->Convert(output.c_str(), cmLocalGenerator::HOME_OUTPUT); + this->Generator->CleanFiles.push_back( + this->Generator->Convert(output.c_str(), + cmLocalGenerator::START_OUTPUT)); + output = this->Generator->Convert(output.c_str(), + cmLocalGenerator::HOME_OUTPUT); // Create a rule to copy the content into the bundle. std::vector<std::string> depends; @@ -399,21 +386,23 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, depends.push_back(input); std::string copyEcho = "Copying OS X content "; copyEcho += output; - this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(), - cmLocalUnixMakefileGenerator3::EchoBuild); + this->Generator->LocalGenerator->AppendEcho( + commands, copyEcho.c_str(), + cmLocalUnixMakefileGenerator3::EchoBuild); std::string copyCommand = "$(CMAKE_COMMAND) -E copy "; - copyCommand += this->Convert(input.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(input.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); copyCommand += " "; - copyCommand += this->Convert(output.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(output.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); commands.push_back(copyCommand); - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - output.c_str(), - depends, commands, false); - this->ExtraFiles.insert(output); + this->Generator->LocalGenerator->WriteMakeRule( + *this->Generator->BuildFileStream, 0, + output.c_str(), + depends, commands, false); + this->Generator->ExtraFiles.insert(output); } //---------------------------------------------------------------------------- @@ -428,12 +417,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) } // Get the full path name of the object file. - bool hasSourceExtension; - std::string objNoTargetDir; - std::string obj = - this->LocalGenerator->GetObjectFileName(*this->Target, source, - &objNoTargetDir, - &hasSourceExtension); + std::string const& objectName = this->GeneratorTarget->Objects[&source]; + std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target); + obj += "/"; + obj += objectName; // Avoid generating duplicate rules. if(this->ObjectFiles.find(obj) == this->ObjectFiles.end()) @@ -487,18 +474,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) AddImplicitDepends(*this->Target, lang, objFullPath.c_str(), srcFullPath.c_str()); - - // add this to the list of objects for this local generator - if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str())) - { - objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir); - } - cmLocalUnixMakefileGenerator3::LocalObjectInfo& info = - this->LocalGenerator->LocalObjectFiles[objNoTargetDir]; - info.HasSourceExtension = hasSourceExtension; - info.push_back( - cmLocalUnixMakefileGenerator3::LocalObjectEntry(this->Target, lang) - ); } //---------------------------------------------------------------------------- @@ -610,14 +585,12 @@ cmMakefileTargetGenerator } // Add language-specific defines. - std::string defines = "$("; - defines += lang; - defines += "_DEFINES)"; + std::set<std::string> defines; // Add source-sepcific preprocessor definitions. if(const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS")) { - this->LocalGenerator->AppendDefines(defines, compile_defs, lang); + this->LocalGenerator->AppendDefines(defines, compile_defs); *this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES = " << compile_defs << "\n" @@ -630,7 +603,7 @@ cmMakefileTargetGenerator if(const char* config_compile_defs = source.GetProperty(defPropName.c_str())) { - this->LocalGenerator->AppendDefines(defines, config_compile_defs, lang); + this->LocalGenerator->AppendDefines(defines, config_compile_defs); *this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_" << configUpper @@ -674,7 +647,7 @@ cmMakefileTargetGenerator this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::MODULE_LIBRARY) { - targetFullPathPDB = this->Target->GetDirectory(this->ConfigName); + targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB += "/"; targetFullPathPDB += this->Target->GetPDBName(this->ConfigName); } @@ -699,7 +672,14 @@ cmMakefileTargetGenerator cmLocalGenerator::SHELL); vars.ObjectDir = objectDir.c_str(); vars.Flags = flags.c_str(); - vars.Defines = defines.c_str(); + + std::string definesString = "$("; + definesString += lang; + definesString += "_DEFINES)"; + + this->LocalGenerator->JoinDefines(defines, definesString, lang); + + vars.Defines = definesString.c_str(); bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) || (strcmp(lang, "CXX") == 0)); @@ -1037,7 +1017,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n"; std::set<cmTarget const*> emitted; const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(cfg)) { cmComputeLinkInformation::ItemVector const& items = cli->GetItems(); for(cmComputeLinkInformation::ItemVector::const_iterator @@ -1069,6 +1050,39 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "SET(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n"; } + // Target-specific include directories: + *this->InfoFileStream + << "\n" + << "# The include file search paths:\n"; + *this->InfoFileStream + << "SET(CMAKE_C_TARGET_INCLUDE_PATH\n"; + std::vector<std::string> includes; + + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); + for(std::vector<std::string>::iterator i = includes.begin(); + i != includes.end(); ++i) + { + *this->InfoFileStream + << " \"" + << this->LocalGenerator->Convert(i->c_str(), + cmLocalGenerator::HOME_OUTPUT) + << "\"\n"; + } + *this->InfoFileStream + << " )\n"; + *this->InfoFileStream + << "SET(CMAKE_CXX_TARGET_INCLUDE_PATH " + << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; + *this->InfoFileStream + << "SET(CMAKE_Fortran_TARGET_INCLUDE_PATH " + << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; + *this->InfoFileStream + << "SET(CMAKE_ASM_TARGET_INCLUDE_PATH " + << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; + // and now write the rule to use it std::vector<std::string> depends; std::vector<std::string> commands; @@ -1401,10 +1415,9 @@ class cmMakefileTargetGeneratorObjectStrings { public: cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings, - cmMakefile* mf, cmLocalUnixMakefileGenerator3* lg, std::string::size_type limit): - Strings(strings), Makefile(mf), LocalGenerator(lg), LengthLimit(limit) + Strings(strings), LocalGenerator(lg), LengthLimit(limit) { this->Space = ""; } @@ -1439,7 +1452,6 @@ public: } private: std::vector<std::string>& Strings; - cmMakefile* Makefile; cmLocalUnixMakefileGenerator3* LocalGenerator; std::string::size_type LengthLimit; std::string CurrentString; @@ -1454,7 +1466,7 @@ cmMakefileTargetGenerator std::string::size_type limit) { cmMakefileTargetGeneratorObjectStrings - helper(objStrings, this->Makefile, this->LocalGenerator, limit); + helper(objStrings, this->LocalGenerator, limit); for(std::vector<std::string>::const_iterator i = this->Objects.begin(); i != this->Objects.end(); ++i) { @@ -1534,7 +1546,11 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() emitted.insert("/System/Library/Frameworks"); #endif std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes); + + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); std::vector<std::string>::iterator i; // check all include directories for frameworks as this // will already have added a -F for the framework @@ -1578,7 +1594,8 @@ void cmMakefileTargetGenerator // Loop over all library dependencies. const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(cfg)) { std::vector<std::string> const& libDeps = cli->GetDepends(); for(std::vector<std::string>::const_iterator j = libDeps.begin(); @@ -1591,7 +1608,7 @@ void cmMakefileTargetGenerator //---------------------------------------------------------------------------- void cmMakefileTargetGenerator -::AppendLinkDepends(std::vector<std::string>& depends) +::AppendObjectDepends(std::vector<std::string>& depends) { // Add dependencies on the compiled object files. std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath(); @@ -1604,25 +1621,32 @@ void cmMakefileTargetGenerator depends.push_back(objTarget); } - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends); + // Add dependencies on the external object files. + for(std::vector<std::string>::const_iterator obj + = this->ExternalObjects.begin(); + obj != this->ExternalObjects.end(); ++obj) + { + depends.push_back(*obj); + } // Add a dependency on the rule file itself. this->LocalGenerator->AppendRuleDepend(depends, this->BuildFileNameFull.c_str()); +} - // Add a dependency on the link definitions file, if any. - if(!this->ModuleDefinitionFile.empty()) - { - depends.push_back(this->ModuleDefinitionFile); - } +//---------------------------------------------------------------------------- +void cmMakefileTargetGenerator +::AppendLinkDepends(std::vector<std::string>& depends) +{ + this->AppendObjectDepends(depends); - // Add dependencies on the external object files. - for(std::vector<std::string>::const_iterator obj - = this->ExternalObjects.begin(); - obj != this->ExternalObjects.end(); ++obj) + // Add dependencies on targets that must be built first. + this->AppendTargetDepends(depends); + + // Add a dependency on the link definitions file, if any. + if(!this->GeneratorTarget->ModuleDefinitionFile.empty()) { - depends.push_back(*obj); + depends.push_back(this->GeneratorTarget->ModuleDefinitionFile); } // Add user-specified dependencies. @@ -1829,8 +1853,15 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES"; bool useResponseFile = this->Makefile->IsOn(responseVar.c_str()); + + std::vector<std::string> includes; + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + lang, config); + std::string includeFlags = - this->LocalGenerator->GetIncludeFlags(lang, useResponseFile); + this->LocalGenerator->GetIncludeFlags(includes, lang, useResponseFile); if(includeFlags.empty()) { return; @@ -1930,7 +1961,10 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes); + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); for(std::vector<std::string>::const_iterator idi = includes.begin(); idi != includes.end(); ++idi) { @@ -1946,7 +1980,7 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) { - if(this->ModuleDefinitionFile.empty()) + if(this->GeneratorTarget->ModuleDefinitionFile.empty()) { return; } @@ -1963,7 +1997,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) // vs6's "cl -link" pass it to the linker. std::string flag = defFileFlag; flag += (this->LocalGenerator->ConvertToLinkReference( - this->ModuleDefinitionFile.c_str())); + this->GeneratorTarget->ModuleDefinitionFile.c_str())); this->LocalGenerator->AppendFlags(flags, flag.c_str()); } |