diff options
30 files changed, 696 insertions, 591 deletions
diff --git a/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst b/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst index f2c875e..a61c702 100644 --- a/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst +++ b/Help/prop_tgt/CONFIG_OUTPUT_NAME.rst @@ -2,6 +2,7 @@ -------------------- Old per-configuration target file base name. +Use :prop_tgt:`OUTPUT_NAME_<CONFIG>` instead. -This is a configuration-specific version of OUTPUT_NAME. Use -OUTPUT_NAME_<CONFIG> instead. +This is a configuration-specific version of the :prop_tgt:`OUTPUT_NAME` +target property. diff --git a/Help/prop_tgt/OUTPUT_NAME.rst b/Help/prop_tgt/OUTPUT_NAME.rst index 97bf010..f1bdb7c 100644 --- a/Help/prop_tgt/OUTPUT_NAME.rst +++ b/Help/prop_tgt/OUTPUT_NAME.rst @@ -6,3 +6,16 @@ Output name for target files. This sets the base name for output files created for an executable or library target. If not set, the logical target name is used by default. + +Contents of ``OUTPUT_NAME`` and the variants listed below may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +See also the variants: + +* :prop_tgt:`OUTPUT_NAME_<CONFIG>` +* :prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>` +* :prop_tgt:`ARCHIVE_OUTPUT_NAME` +* :prop_tgt:`LIBRARY_OUTPUT_NAME_<CONFIG>` +* :prop_tgt:`LIBRARY_OUTPUT_NAME` +* :prop_tgt:`RUNTIME_OUTPUT_NAME_<CONFIG>` +* :prop_tgt:`RUNTIME_OUTPUT_NAME` diff --git a/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst b/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst index 7bfbcbc..41b782f 100644 --- a/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst +++ b/Help/prop_tgt/OUTPUT_NAME_CONFIG.rst @@ -3,4 +3,5 @@ OUTPUT_NAME_<CONFIG> Per-configuration target file base name. -This is the configuration-specific version of OUTPUT_NAME. +This is the configuration-specific version of the :prop_tgt:`OUTPUT_NAME` +target property. diff --git a/Help/release/dev/OUTPUT_NAME-genex.rst b/Help/release/dev/OUTPUT_NAME-genex.rst new file mode 100644 index 0000000..0a39820 --- /dev/null +++ b/Help/release/dev/OUTPUT_NAME-genex.rst @@ -0,0 +1,5 @@ +OUTPUT_NAME-genex +----------------- + +* The :prop_tgt:`OUTPUT_NAME` target property and its variants learned to + support :manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 6940187..d5fe7d1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -165,6 +165,8 @@ set(SRCS cmCommandArgumentLexer.cxx cmCommandArgumentParser.cxx cmCommandArgumentParserHelper.cxx + cmCommonTargetGenerator.cxx + cmCommonTargetGenerator.h cmComputeComponentGraph.cxx cmComputeComponentGraph.h cmComputeLinkDepends.cxx @@ -260,6 +262,8 @@ set(SRCS cmGeneratorExpression.h cmGeneratorTarget.cxx cmGeneratorTarget.h + cmGlobalCommonGenerator.cxx + cmGlobalCommonGenerator.h cmGlobalGenerator.cxx cmGlobalGenerator.h cmGlobalGeneratorFactory.h @@ -285,6 +289,8 @@ set(SRCS cmListFileCache.cxx cmListFileCache.h cmListFileLexer.c + cmLocalCommonGenerator.cxx + cmLocalCommonGenerator.h cmLocalGenerator.cxx cmLocalGenerator.h cmLocalUnixMakefileGenerator3.cxx diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx new file mode 100644 index 0000000..ce351ee --- /dev/null +++ b/Source/cmCommonTargetGenerator.cxx @@ -0,0 +1,360 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmCommonTargetGenerator.h" + +#include "cmComputeLinkInformation.h" +#include "cmGeneratorTarget.h" +#include "cmGlobalCommonGenerator.h" +#include "cmLocalCommonGenerator.h" +#include "cmMakefile.h" +#include "cmSourceFile.h" +#include "cmSystemTools.h" +#include "cmTarget.h" + +cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) + : GeneratorTarget(gt) + , Target(gt->Target) + , Makefile(gt->Makefile) + , LocalGenerator(static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator)) + , GlobalGenerator(static_cast<cmGlobalCommonGenerator*>( + gt->LocalGenerator->GetGlobalGenerator())) + , ConfigName(LocalGenerator->GetConfigName()) + , ModuleDefinitionFile(GeneratorTarget->GetModuleDefinitionFile(ConfigName)) + , FortranModuleDirectoryComputed(false) +{ +} + +cmCommonTargetGenerator::~cmCommonTargetGenerator() +{ +} + +std::string const& cmCommonTargetGenerator::GetConfigName() const +{ + return this->ConfigName; +} + +std::string cmCommonTargetGenerator::Convert( + std::string const& source, + cmLocalGenerator::RelativeRoot relative, + cmLocalGenerator::OutputFormat output) +{ + return this->LocalGenerator->Convert(source, relative, output); +} + +//---------------------------------------------------------------------------- +const char* cmCommonTargetGenerator::GetFeature(const std::string& feature) +{ + return this->GeneratorTarget->GetFeature(feature, this->ConfigName); +} + +//---------------------------------------------------------------------------- +bool cmCommonTargetGenerator::GetFeatureAsBool(const std::string& feature) +{ + return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName); +} + +//---------------------------------------------------------------------------- +void cmCommonTargetGenerator::AddFeatureFlags( + std::string& flags, const std::string& lang + ) +{ + // Add language-specific flags. + this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName); + + if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION")) + { + this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO"); + } +} + +//---------------------------------------------------------------------------- +void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags) +{ + if(this->ModuleDefinitionFile.empty()) + { + return; + } + + // TODO: Create a per-language flag variable. + const char* defFileFlag = + this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG"); + if(!defFileFlag) + { + return; + } + + // Append the flag and value. Use ConvertToLinkReference to help + // vs6's "cl -link" pass it to the linker. + std::string flag = defFileFlag; + flag += (this->LocalGenerator->ConvertToLinkReference( + this->ModuleDefinitionFile)); + this->LocalGenerator->AppendFlags(flags, flag); +} + +//---------------------------------------------------------------------------- +const char* cmCommonTargetGenerator::GetFortranModuleDirectory() +{ + // Compute the module directory. + if(!this->FortranModuleDirectoryComputed) + { + const char* target_mod_dir = + this->Target->GetProperty("Fortran_MODULE_DIRECTORY"); + const char* moddir_flag = + this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG"); + if(target_mod_dir && moddir_flag) + { + // Compute the full path to the module directory. + if(cmSystemTools::FileIsFullPath(target_mod_dir)) + { + // Already a full path. + this->FortranModuleDirectory = target_mod_dir; + } + else + { + // Interpret relative to the current output directory. + this->FortranModuleDirectory = + this->Makefile->GetCurrentBinaryDirectory(); + this->FortranModuleDirectory += "/"; + this->FortranModuleDirectory += target_mod_dir; + } + + // Make sure the module output directory exists. + cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str()); + } + this->FortranModuleDirectoryComputed = true; + } + + // Return the computed directory. + if(this->FortranModuleDirectory.empty()) + { + return 0; + } + else + { + return this->FortranModuleDirectory.c_str(); + } +} + +//---------------------------------------------------------------------------- +void cmCommonTargetGenerator::AddFortranFlags(std::string& flags) +{ + // Enable module output if necessary. + if(const char* modout_flag = + this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG")) + { + this->LocalGenerator->AppendFlags(flags, modout_flag); + } + + // Add a module output directory flag if necessary. + const char* mod_dir = this->GetFortranModuleDirectory(); + if(!mod_dir) + { + mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); + } + if(mod_dir) + { + const char* moddir_flag = + this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"); + std::string modflag = moddir_flag; + modflag += this->Convert(mod_dir, + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + this->LocalGenerator->AppendFlags(flags, modflag); + } + + // If there is a separate module path flag then duplicate the + // include path with it. This compiler does not search the include + // path for modules. + if(const char* modpath_flag = + this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) + { + std::vector<std::string> includes; + const std::string& config = + this->Makefile->GetSafeDefinition("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) + { + std::string flg = modpath_flag; + flg += this->Convert(*idi, + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); + this->LocalGenerator->AppendFlags(flags, flg); + } + } +} + +//---------------------------------------------------------------------------- +void +cmCommonTargetGenerator +::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source) +{ + const char* srcfmt = source.GetProperty("Fortran_FORMAT"); + cmLocalGenerator::FortranFormat format = + this->LocalGenerator->GetFortranFormat(srcfmt); + if(format == cmLocalGenerator::FortranFormatNone) + { + const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT"); + format = this->LocalGenerator->GetFortranFormat(tgtfmt); + } + const char* var = 0; + switch (format) + { + case cmLocalGenerator::FortranFormatFixed: + var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break; + case cmLocalGenerator::FortranFormatFree: + var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break; + default: break; + } + if(var) + { + this->LocalGenerator->AppendFlags( + flags, this->Makefile->GetDefinition(var)); + } +} + +//---------------------------------------------------------------------------- +std::string cmCommonTargetGenerator::GetFrameworkFlags(std::string const& l) +{ + if(!this->Makefile->IsOn("APPLE")) + { + return std::string(); + } + + std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG"; + const char* fwSearchFlag = + this->Makefile->GetDefinition(fwSearchFlagVar); + if(!(fwSearchFlag && *fwSearchFlag)) + { + return std::string(); + } + + std::set<std::string> emitted; +#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */ + emitted.insert("/System/Library/Frameworks"); +#endif + std::vector<std::string> includes; + + const std::string& config = + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + "C", config); + // check all include directories for frameworks as this + // will already have added a -F for the framework + for(std::vector<std::string>::iterator i = includes.begin(); + i != includes.end(); ++i) + { + if(this->Target->NameResolvesToFramework(*i)) + { + std::string frameworkDir = *i; + frameworkDir += "/../"; + frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir); + emitted.insert(frameworkDir); + } + } + + std::string flags; + const char* cfg = this->LocalGenerator->GetConfigName().c_str(); + if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + { + std::vector<std::string> const& frameworks = cli->GetFrameworkPaths(); + for(std::vector<std::string>::const_iterator i = frameworks.begin(); + i != frameworks.end(); ++i) + { + if(emitted.insert(*i).second) + { + flags += fwSearchFlag; + flags += this->LocalGenerator + ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL); + flags += " "; + } + } + } + return flags; +} + +//---------------------------------------------------------------------------- +std::string cmCommonTargetGenerator::GetFlags(const std::string &l) +{ + ByLanguageMap::iterator i = this->FlagsByLanguage.find(l); + if (i == this->FlagsByLanguage.end()) + { + std::string flags; + const char *lang = l.c_str(); + + // Add language feature flags. + this->AddFeatureFlags(flags, lang); + + this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, + lang, this->ConfigName); + + // Fortran-specific flags computed for this target. + if(l == "Fortran") + { + this->AddFortranFlags(flags); + } + + this->LocalGenerator->AddCMP0018Flags(flags, this->Target, + lang, this->ConfigName); + + this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target, + lang); + + // Add include directory flags. + this->AddIncludeFlags(flags, lang); + + // Append old-style preprocessor definition flags. + this->LocalGenerator-> + AppendFlags(flags, this->Makefile->GetDefineFlags()); + + // Add framework directory flags. + this->LocalGenerator-> + AppendFlags(flags,this->GetFrameworkFlags(l)); + + // Add target-specific flags. + this->LocalGenerator->AddCompileOptions(flags, this->Target, + lang, this->ConfigName); + + ByLanguageMap::value_type entry(l, flags); + i = this->FlagsByLanguage.insert(entry).first; + } + return i->second; +} + +std::string cmCommonTargetGenerator::GetDefines(const std::string &l) +{ + ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); + if (i == this->DefinesByLanguage.end()) + { + 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); + } + + // Add preprocessor definitions for this target and configuration. + this->LocalGenerator->AddCompileDefinitions(defines, this->Target, + this->LocalGenerator->GetConfigName(), l); + + std::string definesString; + this->LocalGenerator->JoinDefines(defines, definesString, lang); + + ByLanguageMap::value_type entry(l, definesString); + i = this->DefinesByLanguage.insert(entry).first; + } + return i->second; +} diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h new file mode 100644 index 0000000..e184dba --- /dev/null +++ b/Source/cmCommonTargetGenerator.h @@ -0,0 +1,88 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmCommonTargetGenerator_h +#define cmCommonTargetGenerator_h + +#include "cmStandardIncludes.h" + +#include "cmLocalGenerator.h" + +class cmGeneratorTarget; +class cmGlobalCommonGenerator; +class cmLocalCommonGenerator; +class cmMakefile; +class cmSourceFile; +class cmTarget; + +/** \class cmCommonTargetGenerator + * \brief Common infrastructure for Makefile and Ninja per-target generators + */ +class cmCommonTargetGenerator +{ +public: + cmCommonTargetGenerator(cmGeneratorTarget* gt); + virtual ~cmCommonTargetGenerator(); + + std::string const& GetConfigName() const; + +protected: + + // Add language feature flags. + void AddFeatureFlags(std::string& flags, const std::string& lang); + + // Feature query methods. + const char* GetFeature(const std::string& feature); + bool GetFeatureAsBool(const std::string& feature); + + // Helper to add flag for windows .def file. + void AddModuleDefinitionFlag(std::string& flags); + + cmGeneratorTarget* GeneratorTarget; + cmTarget* Target; + cmMakefile* Makefile; + cmLocalCommonGenerator* LocalGenerator; + cmGlobalCommonGenerator* GlobalGenerator; + std::string ConfigName; + + // The windows module definition source file (.def), if any. + std::string ModuleDefinitionFile; + + // Target-wide Fortran module output directory. + bool FortranModuleDirectoryComputed; + std::string FortranModuleDirectory; + const char* GetFortranModuleDirectory(); + + // Compute target-specific Fortran language flags. + void AddFortranFlags(std::string& flags); + + std::string Convert(std::string const& source, + cmLocalGenerator::RelativeRoot relative, + cmLocalGenerator::OutputFormat output = + cmLocalGenerator::UNCHANGED); + + void AppendFortranFormatFlags(std::string& flags, + cmSourceFile const& source); + + // Return the a string with -F flags on apple + std::string GetFrameworkFlags(std::string const& l); + + virtual void AddIncludeFlags(std::string& flags, + std::string const& lang) = 0; + + typedef std::map<std::string, std::string> ByLanguageMap; + std::string GetFlags(const std::string &l); + ByLanguageMap FlagsByLanguage; + std::string GetDefines(const std::string &l); + ByLanguageMap DefinesByLanguage; +}; + +#endif diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx new file mode 100644 index 0000000..dc8e5a7 --- /dev/null +++ b/Source/cmGlobalCommonGenerator.cxx @@ -0,0 +1,21 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmGlobalCommonGenerator.h" + +cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm): + cmGlobalGenerator(cm) +{ +} + +cmGlobalCommonGenerator::~cmGlobalCommonGenerator() +{ +} diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h new file mode 100644 index 0000000..7bb0e55 --- /dev/null +++ b/Source/cmGlobalCommonGenerator.h @@ -0,0 +1,27 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGlobalCommonGenerator_h +#define cmGlobalCommonGenerator_h + +#include "cmGlobalGenerator.h" + +/** \class cmGlobalCommonGenerator + * \brief Common infrastructure for Makefile and Ninja global generators. + */ +class cmGlobalCommonGenerator : public cmGlobalGenerator +{ +public: + cmGlobalCommonGenerator(cmake* cm); + ~cmGlobalCommonGenerator(); +}; + +#endif diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 722294b..b88b8c8 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -505,7 +505,7 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os, cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm) - : cmGlobalGenerator(cm) + : cmGlobalCommonGenerator(cm) , BuildFileStream(0) , RulesFileStream(0) , CompileCommandsStream(0) diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index ffd1cdc..2a749c1 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -13,7 +13,7 @@ #ifndef cmGlobalNinjaGenerator_h # define cmGlobalNinjaGenerator_h -# include "cmGlobalGenerator.h" +# include "cmGlobalCommonGenerator.h" # include "cmGlobalGeneratorFactory.h" # include "cmNinjaTypes.h" @@ -42,7 +42,7 @@ class cmGeneratorTarget; * - We extensively use Ninja variable overloading system to minimize the * number of generated rules. */ -class cmGlobalNinjaGenerator : public cmGlobalGenerator +class cmGlobalNinjaGenerator : public cmGlobalCommonGenerator { public: /// The default name of Ninja's build file. Typically: build.ninja. diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index e6a67d3..c5fca91 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -21,7 +21,7 @@ #include "cmAlgorithms.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm) - : cmGlobalGenerator(cm) + : cmGlobalCommonGenerator(cm) { // This type of makefile always requires unix style paths this->ForceUnixPaths = true; @@ -483,7 +483,7 @@ cmGlobalUnixMakefileGenerator3 if((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) && (!check_relink || gtarget->Target - ->NeedRelinkBeforeInstall(lg->ConfigurationName))) + ->NeedRelinkBeforeInstall(lg->GetConfigName()))) { std::string tname = lg->GetRelativeTargetDirectory(*gtarget->Target); tname += "/"; @@ -692,7 +692,7 @@ cmGlobalUnixMakefileGenerator3 // Add a local name for the rule to relink the target before // installation. if(gtarget->Target - ->NeedRelinkBeforeInstall(lg->ConfigurationName)) + ->NeedRelinkBeforeInstall(lg->GetConfigName())) { makeTargetName = lg->GetRelativeTargetDirectory(*gtarget->Target); makeTargetName += "/preinstall"; @@ -865,7 +865,7 @@ cmGlobalUnixMakefileGenerator3 // Add rules to prepare the target for installation. if(gtarget->Target - ->NeedRelinkBeforeInstall(lg->ConfigurationName)) + ->NeedRelinkBeforeInstall(lg->GetConfigName())) { localName = lg->GetRelativeTargetDirectory(*gtarget->Target); localName += "/preinstall"; diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 14adf2e..fc53fa8 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -12,7 +12,7 @@ #ifndef cmGlobalUnixMakefileGenerator3_h #define cmGlobalUnixMakefileGenerator3_h -#include "cmGlobalGenerator.h" +#include "cmGlobalCommonGenerator.h" #include "cmGlobalGeneratorFactory.h" class cmGeneratedFileStream; @@ -51,7 +51,7 @@ class cmLocalUnixMakefileGenerator3; */ -class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator +class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator { public: cmGlobalUnixMakefileGenerator3(cmake* cm); diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx new file mode 100644 index 0000000..4583446 --- /dev/null +++ b/Source/cmLocalCommonGenerator.cxx @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmLocalCommonGenerator.h" + +#include "cmMakefile.h" + +cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot): + cmLocalGenerator(gg, parent, snapshot) +{ +} + +cmLocalCommonGenerator::~cmLocalCommonGenerator() +{ +} + +void cmLocalCommonGenerator::SetConfigName() +{ + // Store the configuration name that will be generated. + if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) + { + // Use the build type given by the user. + this->ConfigName = config; + } + else + { + // No configuration type given. + this->ConfigName = ""; + } +} diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h new file mode 100644 index 0000000..af94cda --- /dev/null +++ b/Source/cmLocalCommonGenerator.h @@ -0,0 +1,39 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmLocalCommonGenerator_h +#define cmLocalCommonGenerator_h + +#include "cmLocalGenerator.h" + +class cmCommonTargetGenerator; + +/** \class cmLocalCommonGenerator + * \brief Common infrastructure for Makefile and Ninja local generators. + */ +class cmLocalCommonGenerator: public cmLocalGenerator +{ +public: + cmLocalCommonGenerator(cmGlobalGenerator* gg, + cmLocalGenerator* parent, + cmState::Snapshot snapshot); + ~cmLocalCommonGenerator(); + + std::string const& GetConfigName() { return this->ConfigName; } + +protected: + void SetConfigName(); + std::string ConfigName; + + friend class cmCommonTargetGenerator; +}; + +#endif diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 4db36fc..a293d06 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -25,8 +25,7 @@ cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, cmState::Snapshot snapshot) - : cmLocalGenerator(gg, parent, snapshot) - , ConfigName("") + : cmLocalCommonGenerator(gg, parent, snapshot) , HomeRelativeOutputPath("") { this->TargetImplib = "$TARGET_IMPLIB"; @@ -261,22 +260,6 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os) os << "\n"; } -void cmLocalNinjaGenerator::SetConfigName() -{ - // Store the configuration name that will be generated. - if(const char* config = - this->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE")) - { - // Use the build type given by the user. - this->ConfigName = config; - } - else - { - // No configuration type given. - this->ConfigName = ""; - } -} - //---------------------------------------------------------------------------- void cmLocalNinjaGenerator::ComputeObjectFilenames( std::map<cmSourceFile const*, std::string>& mapping, diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index ce966ff..d10be0c 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -13,7 +13,7 @@ #ifndef cmLocalNinjaGenerator_h # define cmLocalNinjaGenerator_h -# include "cmLocalGenerator.h" +# include "cmLocalCommonGenerator.h" # include "cmNinjaTypes.h" class cmCustomCommandGenerator; @@ -28,7 +28,7 @@ class cmake; * cmLocalNinjaGenerator produces a local build.ninja file from its * member Makefile. */ -class cmLocalNinjaGenerator : public cmLocalGenerator +class cmLocalNinjaGenerator : public cmLocalCommonGenerator { public: cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent, @@ -46,9 +46,6 @@ public: const cmake* GetCMakeInstance() const; cmake* GetCMakeInstance(); - std::string const& GetConfigName() const - { return this->ConfigName; } - /// @returns the relative path between the HomeOutputDirectory and this /// local generators StartOutputDirectory. std::string GetHomeRelativeOutputPath() const @@ -110,8 +107,6 @@ private: void WriteProcessedMakefile(std::ostream& os); void WritePools(std::ostream& os); - void SetConfigName(); - void WriteCustomCommandRule(); void WriteCustomCommandBuildStatement(cmCustomCommand const *cc, const cmNinjaDeps& orderOnlyDeps); @@ -120,7 +115,6 @@ private: std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg); - std::string ConfigName; std::string HomeRelativeOutputPath; typedef std::map<cmCustomCommand const*, std::set<cmTarget*> > diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index e292ba7..5d17a40 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -82,7 +82,7 @@ static std::string cmSplitExtension(std::string const& in, std::string& base) cmLocalUnixMakefileGenerator3:: cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmLocalGenerator* parent, cmState::Snapshot snapshot) - : cmLocalGenerator(gg, parent, snapshot) + : cmLocalCommonGenerator(gg, parent, snapshot) { this->MakefileVariableSize = 0; this->ColorMakefile = false; @@ -100,17 +100,7 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::Generate() { - // Store the configuration name that will be generated. - if(const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) - { - // Use the build type given by the user. - this->ConfigurationName = config; - } - else - { - // No configuration type given. - this->ConfigurationName = ""; - } + this->SetConfigName(); // Record whether some options are enabled to avoid checking many // times later. @@ -497,7 +487,7 @@ void cmLocalUnixMakefileGenerator3 // Add a local name for the rule to relink the target before // installation. if(t->second->Target - ->NeedRelinkBeforeInstall(this->ConfigurationName)) + ->NeedRelinkBeforeInstall(this->ConfigName)) { makeTargetName = this->GetRelativeTargetDirectory(*t->second->Target); makeTargetName += "/preinstall"; @@ -1017,7 +1007,7 @@ cmLocalUnixMakefileGenerator3 for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin(); i != ccs.end(); ++i) { - cmCustomCommandGenerator ccg(*i, this->ConfigurationName, + cmCustomCommandGenerator ccg(*i, this->ConfigName, this->Makefile); this->AppendCustomDepend(depends, ccg); } @@ -1034,7 +1024,7 @@ cmLocalUnixMakefileGenerator3 { // Lookup the real name of the dependency in case it is a CMake target. std::string dep; - if(this->GetRealDependency(*d, this->ConfigurationName, + if(this->GetRealDependency(*d, this->ConfigName, dep)) { depends.push_back(dep); @@ -1053,7 +1043,7 @@ cmLocalUnixMakefileGenerator3 for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin(); i != ccs.end(); ++i) { - cmCustomCommandGenerator ccg(*i, this->ConfigurationName, + cmCustomCommandGenerator ccg(*i, this->ConfigName, this->Makefile); this->AppendCustomCommand(commands, ccg, target, true, relative); } @@ -2043,7 +2033,7 @@ void cmLocalUnixMakefileGenerator3 // Build a list of preprocessor definitions for the target. std::set<std::string> defines; this->AddCompileDefinitions(defines, &target, - this->ConfigurationName, l->first); + this->ConfigName, l->first); if(!defines.empty()) { cmakefileStream diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index b097c95..01ac01b 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -12,7 +12,7 @@ #ifndef cmLocalUnixMakefileGenerator3_h #define cmLocalUnixMakefileGenerator3_h -#include "cmLocalGenerator.h" +#include "cmLocalCommonGenerator.h" // for cmDepends::DependencyVector #include "cmDepends.h" @@ -31,7 +31,7 @@ class cmSourceFile; * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its * member Makefile. */ -class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator +class cmLocalUnixMakefileGenerator3 : public cmLocalCommonGenerator { public: cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, @@ -46,7 +46,6 @@ public: */ virtual void Generate(); - // this returns the relative path between the HomeOutputDirectory and this // local generators StartOutputDirectory const std::string &GetHomeRelativeOutputPath(); @@ -253,8 +252,6 @@ private: ImplicitDependTargetMap ImplicitDepends; - std::string ConfigurationName; - std::string HomeRelativeOutputPath; struct LocalObjectEntry diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 09fad5c..ef4bbbe 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -33,23 +33,19 @@ #include <ctype.h> cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) - : OSXBundleGenerator(0) + : cmCommonTargetGenerator(target) + , OSXBundleGenerator(0) , MacOSXContentGenerator(0) { this->BuildFileStream = 0; this->InfoFileStream = 0; this->FlagFileStream = 0; this->CustomCommandDriver = OnBuild; - this->FortranModuleDirectoryComputed = false; - this->Target = target->Target; - this->Makefile = this->Target->GetMakefile(); this->LocalGenerator = static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator()); - this->ConfigName = this->LocalGenerator->ConfigurationName.c_str(); this->GlobalGenerator = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()); - this->GeneratorTarget = target; cmake* cm = this->GlobalGenerator->GetCMakeInstance(); this->NoRuleMessages = false; if(const char* ruleStatus = cm->GetState() @@ -276,80 +272,6 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() << "\n\n"; } -//---------------------------------------------------------------------------- -std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) -{ - ByLanguageMap::iterator i = this->FlagsByLanguage.find(l); - if (i == this->FlagsByLanguage.end()) - { - std::string flags; - const char *lang = l.c_str(); - - // Add language feature flags. - this->AddFeatureFlags(flags, lang); - - this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, - lang, this->ConfigName); - - // Fortran-specific flags computed for this target. - if(l == "Fortran") - { - this->AddFortranFlags(flags); - } - - this->LocalGenerator->AddCMP0018Flags(flags, this->Target, - lang, this->ConfigName); - - this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target, - lang); - - // Add include directory flags. - this->AddIncludeFlags(flags, lang); - - // Append old-style preprocessor definition flags. - this->LocalGenerator-> - AppendFlags(flags, this->Makefile->GetDefineFlags()); - - // Add include directory flags. - this->LocalGenerator-> - AppendFlags(flags,this->GetFrameworkFlags(l)); - - // Add target-specific flags. - this->LocalGenerator->AddCompileOptions(flags, this->Target, - lang, this->ConfigName); - - ByLanguageMap::value_type entry(l, flags); - i = this->FlagsByLanguage.insert(entry).first; - } - return i->second; -} - -std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) -{ - ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); - if (i == this->DefinesByLanguage.end()) - { - 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); - } - - // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AddCompileDefinitions(defines, this->Target, - this->LocalGenerator->ConfigurationName, l); - - std::string definesString; - this->LocalGenerator->JoinDefines(defines, definesString, lang); - - ByLanguageMap::value_type entry(l, definesString); - i = this->DefinesByLanguage.insert(entry).first; - } - return i->second; -} - void cmMakefileTargetGenerator::WriteTargetLanguageFlags() { // write language flags for target @@ -511,35 +433,6 @@ void cmMakefileTargetGenerator //---------------------------------------------------------------------------- void cmMakefileTargetGenerator -::AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source) -{ - const char* srcfmt = source.GetProperty("Fortran_FORMAT"); - cmLocalGenerator::FortranFormat format = - this->LocalGenerator->GetFortranFormat(srcfmt); - if(format == cmLocalGenerator::FortranFormatNone) - { - const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT"); - format = this->LocalGenerator->GetFortranFormat(tgtfmt); - } - const char* var = 0; - switch (format) - { - case cmLocalGenerator::FortranFormatFixed: - var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break; - case cmLocalGenerator::FortranFormatFree: - var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break; - default: break; - } - if(var) - { - this->LocalGenerator->AppendFlags( - flags, this->Makefile->GetDefinition(var)); - } -} - -//---------------------------------------------------------------------------- -void -cmMakefileTargetGenerator ::WriteObjectBuildFile(std::string &obj, const std::string& lang, cmSourceFile const& source, @@ -567,7 +460,7 @@ cmMakefileTargetGenerator this->LocalGenerator->AppendFlags(flags, langFlags); std::string configUpper = - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); + cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName()); // Add Fortran format flags. if(lang == "Fortran") @@ -1158,7 +1051,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "# Targets to which this target links.\n" << "set(CMAKE_TARGET_LINKED_INFO_FILES\n"; std::set<cmTarget const*> emitted; - const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); + const char* cfg = this->LocalGenerator->GetConfigName().c_str(); if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { cmComputeLinkInformation::ItemVector const& items = cli->GetItems(); @@ -1558,67 +1451,6 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule( } //---------------------------------------------------------------------------- -std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l) -{ - if(!this->Makefile->IsOn("APPLE")) - { - return std::string(); - } - - std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG"; - const char* fwSearchFlag = - this->Makefile->GetDefinition(fwSearchFlagVar); - if(!(fwSearchFlag && *fwSearchFlag)) - { - return std::string(); - } - - std::set<std::string> emitted; -#ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */ - emitted.insert("/System/Library/Frameworks"); -#endif - std::vector<std::string> includes; - - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - this->LocalGenerator->GetIncludeDirectories(includes, - this->GeneratorTarget, - "C", config); - // check all include directories for frameworks as this - // will already have added a -F for the framework - for(std::vector<std::string>::iterator i = includes.begin(); - i != includes.end(); ++i) - { - if(this->Target->NameResolvesToFramework(*i)) - { - std::string frameworkDir = *i; - frameworkDir += "/../"; - frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir); - emitted.insert(frameworkDir); - } - } - - std::string flags; - const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) - { - std::vector<std::string> const& frameworks = cli->GetFrameworkPaths(); - for(std::vector<std::string>::const_iterator i = frameworks.begin(); - i != frameworks.end(); ++i) - { - if(emitted.insert(*i).second) - { - flags += fwSearchFlag; - flags += this->LocalGenerator - ->ConvertToOutputFormat(*i, cmLocalGenerator::SHELL); - flags += " "; - } - } - } - return flags; -} - -//---------------------------------------------------------------------------- void cmMakefileTargetGenerator ::AppendTargetDepends(std::vector<std::string>& depends) { @@ -1629,7 +1461,7 @@ void cmMakefileTargetGenerator } // Loop over all library dependencies. - const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); + const char* cfg = this->LocalGenerator->GetConfigName().c_str(); if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { std::vector<std::string> const& libDeps = cli->GetDepends(); @@ -1671,11 +1503,9 @@ void cmMakefileTargetGenerator this->AppendTargetDepends(depends); // Add a dependency on the link definitions file, if any. - std::string def = this->GeneratorTarget->GetModuleDefinitionFile( - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); - if(!def.empty()) + if(!this->ModuleDefinitionFile.empty()) { - depends.push_back(def); + depends.push_back(this->ModuleDefinitionFile); } // Add user-specified dependencies. @@ -1982,149 +1812,3 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, this->LocalGenerator->AppendFlags(flags, includeFlags); } } - -//---------------------------------------------------------------------------- -const char* cmMakefileTargetGenerator::GetFortranModuleDirectory() -{ - // Compute the module directory. - if(!this->FortranModuleDirectoryComputed) - { - const char* target_mod_dir = - this->Target->GetProperty("Fortran_MODULE_DIRECTORY"); - const char* moddir_flag = - this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG"); - if(target_mod_dir && moddir_flag) - { - // Compute the full path to the module directory. - if(cmSystemTools::FileIsFullPath(target_mod_dir)) - { - // Already a full path. - this->FortranModuleDirectory = target_mod_dir; - } - else - { - // Interpret relative to the current output directory. - this->FortranModuleDirectory = - this->Makefile->GetCurrentBinaryDirectory(); - this->FortranModuleDirectory += "/"; - this->FortranModuleDirectory += target_mod_dir; - } - - // Make sure the module output directory exists. - cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str()); - } - this->FortranModuleDirectoryComputed = true; - } - - // Return the computed directory. - if(this->FortranModuleDirectory.empty()) - { - return 0; - } - else - { - return this->FortranModuleDirectory.c_str(); - } -} - -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) -{ - // Enable module output if necessary. - if(const char* modout_flag = - this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG")) - { - this->LocalGenerator->AppendFlags(flags, modout_flag); - } - - // Add a module output directory flag if necessary. - const char* mod_dir = this->GetFortranModuleDirectory(); - if(!mod_dir) - { - mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT"); - } - if(mod_dir) - { - const char* moddir_flag = - this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"); - std::string modflag = moddir_flag; - modflag += this->Convert(mod_dir, - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL); - this->LocalGenerator->AppendFlags(flags, modflag); - } - - // If there is a separate module path flag then duplicate the - // include path with it. This compiler does not search the include - // path for modules. - if(const char* modpath_flag = - this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) - { - std::vector<std::string> includes; - const std::string& config = - this->Makefile->GetSafeDefinition("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) - { - std::string flg = modpath_flag; - flg += this->Convert(*idi, - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); - this->LocalGenerator->AppendFlags(flags, flg); - } - } -} - -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) -{ - std::string def = this->GeneratorTarget->GetModuleDefinitionFile( - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); - if(def.empty()) - { - return; - } - - // TODO: Create a per-language flag variable. - const char* defFileFlag = - this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG"); - if(!defFileFlag) - { - return; - } - - // Append the flag and value. Use ConvertToLinkReference to help - // vs6's "cl -link" pass it to the linker. - std::string flag = defFileFlag; - flag += (this->LocalGenerator->ConvertToLinkReference(def)); - this->LocalGenerator->AppendFlags(flags, flag); -} - -//---------------------------------------------------------------------------- -const char* cmMakefileTargetGenerator::GetFeature(const std::string& feature) -{ - return this->GeneratorTarget->GetFeature(feature, this->ConfigName); -} - -//---------------------------------------------------------------------------- -bool cmMakefileTargetGenerator::GetFeatureAsBool(const std::string& feature) -{ - return this->GeneratorTarget->GetFeatureAsBool(feature, this->ConfigName); -} - -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::AddFeatureFlags( - std::string& flags, const std::string& lang - ) -{ - // Add language-specific flags. - this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName); - - if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION")) - { - this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO"); - } -} diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 9182236..b885672 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -12,6 +12,8 @@ #ifndef cmMakefileTargetGenerator_h #define cmMakefileTargetGenerator_h +#include "cmCommonTargetGenerator.h" + #include "cmLocalUnixMakefileGenerator3.h" #include "cmOSXBundleGenerator.h" @@ -30,7 +32,7 @@ class cmSourceFile; * \brief Support Routines for writing makefiles * */ -class cmMakefileTargetGenerator +class cmMakefileTargetGenerator: public cmCommonTargetGenerator { public: // constructor to set the ivars @@ -124,12 +126,6 @@ protected: void DriveCustomCommands(std::vector<std::string>& depends); - // Return the a string with -F flags on apple - std::string GetFrameworkFlags(std::string const& l); - - void AppendFortranFormatFlags(std::string& flags, - cmSourceFile const& source); - // append intertarget dependencies void AppendTargetDepends(std::vector<std::string>& depends); @@ -173,12 +169,8 @@ protected: virtual void CloseFileStreams(); void RemoveForbiddenFlags(const char* flagVar, const std::string& linkLang, std::string& linkFlags); - cmTarget *Target; - cmGeneratorTarget* GeneratorTarget; cmLocalUnixMakefileGenerator3 *LocalGenerator; cmGlobalUnixMakefileGenerator3 *GlobalGenerator; - cmMakefile *Makefile; - std::string ConfigName; enum CustomCommandDriveType { OnBuild, OnDepends, OnUtility }; CustomCommandDriveType CustomCommandDriver; @@ -242,42 +234,6 @@ protected: std::set<std::string> MacContentFolders; cmOSXBundleGenerator* OSXBundleGenerator; MacOSXContentGeneratorType* MacOSXContentGenerator; - - typedef std::map<std::string, std::string> ByLanguageMap; - std::string GetFlags(const std::string &l); - ByLanguageMap FlagsByLanguage; - std::string GetDefines(const std::string &l); - ByLanguageMap DefinesByLanguage; - - // Target-wide Fortran module output directory. - bool FortranModuleDirectoryComputed; - std::string FortranModuleDirectory; - const char* GetFortranModuleDirectory(); - - // Compute target-specific Fortran language flags. - void AddFortranFlags(std::string& flags); - - // Helper to add flag for windows .def file. - void AddModuleDefinitionFlag(std::string& flags); - - // Add language feature flags. - void AddFeatureFlags(std::string& flags, const std::string& lang); - - // Feature query methods. - const char* GetFeature(const std::string& feature); - bool GetFeatureAsBool(const std::string& feature); - - //================================================================== - // Convenience routines that do nothing more than forward to - // implementaitons - std::string Convert(const std::string& source, - cmLocalGenerator::RelativeRoot relative, - cmLocalGenerator::OutputFormat output = - cmLocalGenerator::UNCHANGED) - { - return this->LocalGenerator->Convert(source, relative, output); - } - }; #endif diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index b18f368..a72bc72 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -58,17 +58,14 @@ cmNinjaTargetGenerator::New(cmGeneratorTarget* target) } cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target) - : + : cmCommonTargetGenerator(target), MacOSXContentGenerator(0), OSXBundleGenerator(0), MacContentFolders(), - Target(target->Target), - Makefile(target->Makefile), LocalGenerator( static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator())), Objects() { - this->GeneratorTarget = target; MacOSXContentGenerator = new MacOSXContentGeneratorType(this); } @@ -92,11 +89,6 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const return this->LocalGenerator->GetGlobalNinjaGenerator(); } -std::string const& cmNinjaTargetGenerator::GetConfigName() const -{ - return this->LocalGenerator->GetConfigName(); -} - std::string cmNinjaTargetGenerator::LanguageCompilerRule( const std::string& lang) const { @@ -104,32 +96,6 @@ std::string cmNinjaTargetGenerator::LanguageCompilerRule( cmGlobalNinjaGenerator::EncodeRuleName(this->Target->GetName()); } -// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. -const char* cmNinjaTargetGenerator::GetFeature(const std::string& feature) -{ - return this->GeneratorTarget->GetFeature(feature, this->GetConfigName()); -} - -// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. -bool cmNinjaTargetGenerator::GetFeatureAsBool(const std::string& feature) -{ - return this->GeneratorTarget->GetFeatureAsBool(feature, - this->GetConfigName()); -} - -// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. -void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags, - const std::string& lang) -{ - // Add language-specific flags. - this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName()); - - if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION")) - { - this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO"); - } -} - std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget() { @@ -144,71 +110,37 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile const* source, const std::string& language) { - // TODO: Fortran support. - // // Fortran-specific flags computed for this target. - // if(*l == "Fortran") - // { - // this->AddFortranFlags(flags); - // } - - bool hasLangCached = this->LanguageFlags.count(language) != 0; - std::string& languageFlags = this->LanguageFlags[language]; - if(!hasLangCached) - { - this->AddFeatureFlags(languageFlags, language); - - this->GetLocalGenerator()->AddArchitectureFlags(languageFlags, - this->GeneratorTarget, - language, - this->GetConfigName()); - - // Add shared-library flags if needed. - this->LocalGenerator->AddCMP0018Flags(languageFlags, this->Target, - language, - this->GetConfigName()); - - this->LocalGenerator->AddVisibilityPresetFlags(languageFlags, this->Target, - language); - - std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes, - this->GeneratorTarget, - language, - this->GetConfigName()); - // Add include directory flags. - std::string includeFlags = - this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget, - language, - language == "RC" ? true : false, // full include paths for RC - // needed by cmcldeps - false, - this->GetConfigName()); - if (this->GetGlobalGenerator()->IsGCCOnWindows()) - cmSystemTools::ReplaceString(includeFlags, "\\", "/"); - - this->LocalGenerator->AppendFlags(languageFlags, includeFlags); - - // Append old-style preprocessor definition flags. - this->LocalGenerator->AppendFlags(languageFlags, - this->Makefile->GetDefineFlags()); - - // Add target-specific flags. - this->LocalGenerator->AddCompileOptions(languageFlags, this->Target, - language, - this->GetConfigName()); - } - - std::string flags = languageFlags; + std::string flags = this->GetFlags(language); // Add source file specific flags. this->LocalGenerator->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS")); - // TODO: Handle Apple frameworks. - return flags; } +void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags, + std::string const& language) +{ + std::vector<std::string> includes; + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, + language, + this->GetConfigName()); + // Add include directory flags. + std::string includeFlags = + this->LocalGenerator->GetIncludeFlags(includes, this->GeneratorTarget, + language, + language == "RC" ? true : false, // full include paths for RC + // needed by cmcldeps + false, + this->GetConfigName()); + if (this->GetGlobalGenerator()->IsGCCOnWindows()) + cmSystemTools::ReplaceString(includeFlags, "\\", "/"); + + this->LocalGenerator->AppendFlags(languageFlags, includeFlags); +} + bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const { if (lang == "C" || lang == "CXX") @@ -231,16 +163,6 @@ cmNinjaTargetGenerator:: ComputeDefines(cmSourceFile const* source, const std::string& language) { std::set<std::string> defines; - - // Add the export symbol definition for shared library objects. - if(const char* exportMacro = this->Target->GetExportMacro()) - { - this->LocalGenerator->AppendDefines(defines, exportMacro); - } - - // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AddCompileDefinitions(defines, this->Target, - this->GetConfigName(), language); this->LocalGenerator->AppendDefines (defines, source->GetProperty("COMPILE_DEFINITIONS")); @@ -252,7 +174,7 @@ ComputeDefines(cmSourceFile const* source, const std::string& language) source->GetProperty(defPropName)); } - std::string definesString; + std::string definesString = this->GetDefines(language); this->LocalGenerator->JoinDefines(defines, definesString, language); @@ -278,7 +200,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const // Add a dependency on the link definitions file, if any. if(!this->ModuleDefinitionFile.empty()) { - result.push_back(this->ModuleDefinitionFile); + result.push_back(this->ConvertToNinjaPath(this->ModuleDefinitionFile)); } return result; @@ -608,11 +530,6 @@ cmNinjaTargetGenerator { this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty()); } - std::string def = this->GeneratorTarget->GetModuleDefinitionFile(config); - if(!def.empty()) - { - this->ModuleDefinitionFile = this->ConvertToNinjaPath(def); - } this->GetBuildFileStream() << "\n"; } @@ -762,32 +679,6 @@ cmNinjaTargetGenerator } } -//---------------------------------------------------------------------------- -void -cmNinjaTargetGenerator -::AddModuleDefinitionFlag(std::string& flags) -{ - if(this->ModuleDefinitionFile.empty()) - { - return; - } - - // TODO: Create a per-language flag variable. - const char* defFileFlag = - this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG"); - if(!defFileFlag) - { - return; - } - - // Append the flag and value. Use ConvertToLinkReference to help - // vs6's "cl -link" pass it to the linker. - std::string flag = defFileFlag; - flag += (this->LocalGenerator->ConvertToLinkReference( - this->ModuleDefinitionFile)); - this->LocalGenerator->AppendFlags(flags, flag); -} - void cmNinjaTargetGenerator ::EnsureDirectoryExists(const std::string& path) const diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index fc361b2..8912431 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -13,6 +13,8 @@ #ifndef cmNinjaTargetGenerator_h #define cmNinjaTargetGenerator_h +#include "cmCommonTargetGenerator.h" + #include "cmStandardIncludes.h" #include "cmNinjaTypes.h" #include "cmLocalNinjaGenerator.h" @@ -26,7 +28,7 @@ class cmMakefile; class cmSourceFile; class cmCustomCommand; -class cmNinjaTargetGenerator +class cmNinjaTargetGenerator: public cmCommonTargetGenerator { public: /// Create a cmNinjaTargetGenerator according to the @a target's type. @@ -65,14 +67,8 @@ protected: cmMakefile* GetMakefile() const { return this->Makefile; } - std::string const& GetConfigName() const; - std::string LanguageCompilerRule(const std::string& lang) const; - const char* GetFeature(const std::string& feature); - bool GetFeatureAsBool(const std::string& feature); - void AddFeatureFlags(std::string& flags, const std::string& lang); - std::string OrderDependsTargetForTarget(); std::string ComputeOrderDependsForTarget(); @@ -85,6 +81,8 @@ protected: std::string ComputeFlagsForObject(cmSourceFile const* source, const std::string& language); + void AddIncludeFlags(std::string& flags, std::string const& lang); + std::string ComputeDefines(cmSourceFile const* source, const std::string& language); @@ -119,9 +117,6 @@ protected: cmNinjaDeps GetObjects() const { return this->Objects; } - // Helper to add flag for windows .def file. - void AddModuleDefinitionFlag(std::string& flags); - void EnsureDirectoryExists(const std::string& dir) const; void EnsureParentDirectoryExists(const std::string& path) const; @@ -150,19 +145,10 @@ protected: cmNinjaVars& vars); private: - cmTarget* Target; - cmGeneratorTarget* GeneratorTarget; - cmMakefile* Makefile; cmLocalNinjaGenerator* LocalGenerator; /// List of object files for this target. cmNinjaDeps Objects; std::vector<cmCustomCommand const*> CustomCommands; - - typedef std::map<std::string, std::string> LanguageFlagMap; - LanguageFlagMap LanguageFlags; - - // The windows module definition source file (.def), if any. - std::string ModuleDefinitionFile; }; #endif // ! cmNinjaTargetGenerator_h diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 32b9566..58f4bf4 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -190,7 +190,7 @@ std::string cmQtAutoGenerators::ListQt5RccInputs(cmSourceFile* sf, std::vector<std::string> command; command.push_back(rccCommand); - command.push_back("--list"); + command.push_back("-list"); std::string absFile = cmsys::SystemTools::GetRealPath( sf->GetFullPath()); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 3353fbd..2b73e6f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4597,15 +4597,25 @@ std::string cmTarget::GetOutputName(const std::string& config, // OUTPUT_NAME props.push_back("OUTPUT_NAME"); + std::string outName; for(std::vector<std::string>::const_iterator i = props.begin(); i != props.end(); ++i) { - if(const char* outName = this->GetProperty(*i)) + if (const char* outNameProp = this->GetProperty(*i)) { - return outName; + outName = outNameProp; + break; } } - return this->GetName(); + + if (outName.empty()) + { + outName = this->GetName(); + } + + cmGeneratorExpression ge; + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName); + return cge->Evaluate(this->Makefile, config); } //---------------------------------------------------------------------------- diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index 0df42d9..df3f178 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -73,6 +73,12 @@ install(TARGETS testLibPerConfigDest EXPORT exp DESTINATION lib/$<$<BOOL:$<CONFIG>>:$<CONFIG>>$<$<NOT:$<BOOL:$<CONFIG>>>:NoConfig> ) +# Test OUTPUT_NAME properties with generator expressions +add_library(testLib7 STATIC testLib7.c) +set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_DEBUG testLib7D-$<CONFIG>) +set_property(TARGET testLib7 PROPERTY OUTPUT_NAME_RELEASE testLib7R-$<CONFIG>) +set_property(TARGET testLib7 PROPERTY OUTPUT_NAME testLib7-$<CONFIG>) + # Work-around: Visual Studio 6 does not support per-target object files. set(VS6) if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6") @@ -446,7 +452,7 @@ install( TARGETS testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3 testExe2lib testLib4lib testLib4libdbg testLib4libopt - testLib6 + testLib6 testLib7 testLibCycleA testLibCycleB cmp0022NEW cmp0022OLD systemlib @@ -505,7 +511,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3 NAMESPACE bld_ FILE ExportBuildTree.cmake ) -export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib +export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe2lib testLib4lib testLib4libdbg testLib4libopt testLibCycleA testLibCycleB testLibPerConfigDest diff --git a/Tests/ExportImport/Export/testLib7.c b/Tests/ExportImport/Export/testLib7.c new file mode 100644 index 0000000..7acae9e --- /dev/null +++ b/Tests/ExportImport/Export/testLib7.c @@ -0,0 +1 @@ +int testLib7(void) { return 0; } diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 17d983a..a74bad1 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -33,6 +33,7 @@ target_link_libraries(imp_testExe1 exp_testLib4 exp_testLib5 exp_testLib6 + exp_testLib7 exp_testLibCycleA exp_testLibPerConfigDest ) @@ -66,6 +67,7 @@ target_link_libraries(imp_testExe1b bld_testLib4 bld_testLib5 bld_testLib6 + bld_testLib7 bld_testLibCycleA bld_testLibPerConfigDest ) diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c index 150fcef..56cdd2c 100644 --- a/Tests/ExportImport/Import/A/imp_testExe1.c +++ b/Tests/ExportImport/Import/A/imp_testExe1.c @@ -6,6 +6,7 @@ extern int testLib4(); extern int testLib4lib(); extern int testLib5(); extern int testLib6(); +extern int testLib7(); extern int testLibCycleA1(); extern int testLibPerConfigDest(); @@ -21,7 +22,7 @@ extern testLib4libcfg(void); int main() { return (testLib2() + generated_by_testExe1() + testLib3() + testLib4() - + testLib5() + testLib6() + testLibCycleA1() + + testLib5() + testLib6() + testLib7() + testLibCycleA1() + testLibPerConfigDest() + generated_by_testExe3() + testLib4lib() + testLib4libcfg()); } @@ -248,6 +248,7 @@ CMAKE_CXX_SOURCES="\ cmCommandArgumentLexer \ cmCommandArgumentParser \ cmCommandArgumentParserHelper \ + cmCommonTargetGenerator \ cmCPackPropertiesGenerator \ cmDefinitions \ cmDepends \ @@ -276,8 +277,10 @@ CMAKE_CXX_SOURCES="\ cmGeneratorExpressionNode \ cmGeneratorExpressionParser \ cmGeneratorExpression \ + cmGlobalCommonGenerator \ cmGlobalGenerator \ cmInstallDirectoryGenerator \ + cmLocalCommonGenerator \ cmLocalGenerator \ cmInstalledFile \ cmInstallGenerator \ |