Kaynağa Gözat

Merge topic 'vs-masm'

cbd1d42b Help: Add notes for topic 'vs-masm'
0f8522a6 VS: Add MASM support to VS 8 and 9 (#8170, #14984)
a43f4400 VS: Move internal MasmEnabled member up to VS 7 generator
df3b007d VS: Add test for MASM support
e8727449 VS: Populate MASM tool build settings in .vcxproj files
0271a5f9 VS: Manually fix MASM flag table entries
1d662e48 VS: Generate MASM flag tables from MSBuild tool files
4f6940df VS: Fix ASM_MASM support in VS >= 10
d7866c52 ASM_MASM: Fix selection of ml64
0374abdb ASM_MASM: Add preprocessor definitions to compile lines
5b0a46e1 ASM_MASM: Do not require compiler to be a full path
802dbe52 cmLocalVisualStudio7Generator: Rename local 'lang' var
Brad King 11 yıl önce
ebeveyn
işleme
8c30014982

+ 5 - 0
Help/release/dev/vs-masm.rst

@@ -0,0 +1,5 @@
+vs-masm
+-------
+
+* Visual Studio generators for VS 8 and later learned to support
+  the ``ASM_MASM`` language.

+ 1 - 1
Modules/CMakeASM_MASMInformation.cmake

@@ -18,7 +18,7 @@ set(ASM_DIALECT "_MASM")
 
 set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
 
-set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> /c  /Fo <OBJECT> <SOURCE>")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <FLAGS> /c  /Fo <OBJECT> <SOURCE>")
 
 include(CMakeASMInformation)
 set(ASM_DIALECT)

+ 2 - 1
Modules/CMakeDetermineASM_MASMCompiler.cmake

@@ -17,7 +17,8 @@
 set(ASM_DIALECT "_MASM")
 
 # if we are using the 64bit cl compiler, assume we also want the 64bit assembler
-if(CMAKE_CL_64)
+if(";${CMAKE_VS_PLATFORM_NAME};${MSVC_C_ARCHITECTURE_ID};${MSVC_CXX_ARCHITECTURE_ID};"
+    MATCHES ";(Win64|Itanium|x64|IA64);")
    set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ml64)
 else()
    set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ml)

+ 2 - 1
Source/cmGlobalGenerator.cxx

@@ -620,7 +620,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
         "No " << compilerName << " could be found.\n"
         ;
       }
-    else if(strcmp(lang, "RC") != 0)
+    else if(strcmp(lang, "RC") != 0 &&
+            strcmp(lang, "ASM_MASM") != 0)
       {
       if(!cmSystemTools::FileIsFullPath(compilerFile))
         {

+ 0 - 10
Source/cmGlobalVisualStudio10Generator.cxx

@@ -99,7 +99,6 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
     "ProductDir", vc10Express, cmSystemTools::KeyWOW64_32);
   this->SystemIsWindowsPhone = false;
   this->SystemIsWindowsStore = false;
-  this->MasmEnabled = false;
   this->MSBuildCommandInitialized = false;
 }
 
@@ -257,15 +256,6 @@ void cmGlobalVisualStudio10Generator
 ::EnableLanguage(std::vector<std::string>const &  lang,
                  cmMakefile *mf, bool optional)
 {
-  for(std::vector<std::string>::const_iterator it = lang.begin();
-      it != lang.end(); ++it)
-    {
-    if(*it == "ASM_MASM")
-      {
-      this->MasmEnabled = true;
-      }
-    }
-
   cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
 }
 

+ 0 - 4
Source/cmGlobalVisualStudio10Generator.h

@@ -58,9 +58,6 @@ public:
   /** Is the installed VS an Express edition?  */
   bool IsExpressEdition() const { return this->ExpressEdition; }
 
-  /** Is the Microsoft Assembler enabled?  */
-  bool IsMasmEnabled() const { return this->MasmEnabled; }
-
   /** The toolset name for the target platform.  */
   const char* GetPlatformToolset() const;
 
@@ -123,7 +120,6 @@ protected:
   bool SystemIsWindowsPhone;
   bool SystemIsWindowsStore;
   bool ExpressEdition;
-  bool MasmEnabled;
 
   bool UseFolderProperty();
 

+ 1 - 0
Source/cmGlobalVisualStudio7Generator.cxx

@@ -23,6 +23,7 @@ cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator(
 {
   this->IntelProjectVersion = 0;
   this->DevEnvCommandInitialized = false;
+  this->MasmEnabled = false;
 
   if (platformName.empty())
     {

+ 4 - 0
Source/cmGlobalVisualStudio7Generator.h

@@ -102,6 +102,9 @@ public:
 
   virtual void FindMakeProgram(cmMakefile*);
 
+  /** Is the Microsoft Assembler enabled?  */
+  bool IsMasmEnabled() const { return this->MasmEnabled; }
+
   // Encoding for Visual Studio files
   virtual std::string Encoding();
 
@@ -173,6 +176,7 @@ protected:
   // There is one SLN file per project.
   std::string CurrentProject;
   std::string PlatformName;
+  bool MasmEnabled;
 
 private:
   char* IntelProjectVersion;

+ 8 - 0
Source/cmGlobalVisualStudio8Generator.cxx

@@ -136,6 +136,14 @@ void cmGlobalVisualStudio8Generator
 ::EnableLanguage(std::vector<std::string>const &  lang,
                  cmMakefile *mf, bool optional)
 {
+  for(std::vector<std::string>::const_iterator it = lang.begin();
+      it != lang.end(); ++it)
+    {
+    if(*it == "ASM_MASM")
+      {
+      this->MasmEnabled = true;
+      }
+    }
   this->AddPlatformDefinitions(mf);
   cmGlobalVisualStudio7Generator::EnableLanguage(lang, mf, optional);
 }

+ 54 - 3
Source/cmLocalVisualStudio7Generator.cxx

@@ -44,6 +44,16 @@ private:
 
 extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
 
+static void cmConvertToWindowsSlash(std::string& s)
+{
+  std::string::size_type pos = 0;
+  while((pos = s.find('/', pos)) != std::string::npos)
+    {
+    s[pos] = '\\';
+    pos++;
+    }
+}
+
 //----------------------------------------------------------------------------
 cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(VSVersion v):
   cmLocalVisualStudioGenerator(v)
@@ -862,6 +872,31 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
       }
     }
   fout << "/>\n";  // end of <Tool Name=VCCLCompilerTool
+  if(gg->IsMasmEnabled() && !this->FortranProject)
+    {
+    Options masmOptions(this, Options::MasmCompiler, 0, 0);
+    fout <<
+      "\t\t\t<Tool\n"
+      "\t\t\t\tName=\"MASM\"\n"
+      "\t\t\t\tIncludePaths=\""
+      ;
+    const char* sep = "";
+    for(i = includes.begin(); i != includes.end(); ++i)
+      {
+      std::string inc = *i;
+      cmConvertToWindowsSlash(inc);
+      fout << sep << this->EscapeForXML(inc);
+      sep = ";";
+      }
+    fout << "\"\n";
+    // Use same preprocessor definitions as VCCLCompilerTool.
+    targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
+                                                "ASM_MASM");
+    masmOptions.OutputFlagMap(fout, "\t\t\t\t");
+    fout <<
+      "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
+      "\t\t\t/>\n";
+    }
   tool = "VCCustomBuildTool";
   if(this->FortranProject)
     {
@@ -1695,11 +1730,12 @@ bool cmLocalVisualStudio7Generator
       else if(!fcinfo.FileConfigMap.empty())
         {
         const char* aCompilerTool = "VCCLCompilerTool";
-        const char* lang = "CXX";
+        const char* ppLang = "CXX";
         if(this->FortranProject)
           {
           aCompilerTool = "VFFortranCompilerTool";
           }
+        std::string const& lang = (*sf)->GetLanguage();
         std::string ext = (*sf)->GetExtension();
         ext = cmSystemTools::LowerCase(ext);
         if(ext == "idl")
@@ -1713,7 +1749,7 @@ bool cmLocalVisualStudio7Generator
         if(ext == "rc")
           {
           aCompilerTool = "VCResourceCompilerTool";
-          lang = "RC";
+          ppLang = "RC";
           if(this->FortranProject)
             {
             aCompilerTool = "VFResourceCompilerTool";
@@ -1727,6 +1763,11 @@ bool cmLocalVisualStudio7Generator
             aCompilerTool = "VFCustomBuildTool";
             }
           }
+        if (gg->IsMasmEnabled() && !this->FortranProject &&
+            lang == "ASM_MASM")
+          {
+          aCompilerTool = "MASM";
+          }
         for(std::map<std::string, cmLVS7GFileConfig>::const_iterator
               fci = fcinfo.FileConfigMap.begin();
             fci != fcinfo.FileConfigMap.end(); ++fci)
@@ -1763,7 +1804,7 @@ bool cmLocalVisualStudio7Generator
             fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
             fileOptions.OutputPreprocessorDefinitions(fout,
                                                       "\t\t\t\t\t", "\n",
-                                                      lang);
+                                                      ppLang);
             }
           if(!fc.AdditionalDeps.empty())
             {
@@ -2095,6 +2136,16 @@ cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
        << "\t<Platforms>\n"
        << "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
        << "\t</Platforms>\n";
+  if(gg->IsMasmEnabled())
+    {
+    fout <<
+      "\t<ToolFiles>\n"
+      "\t\t<DefaultToolFile\n"
+      "\t\t\tFileName=\"masm.rules\"\n"
+      "\t\t/>\n"
+      "\t</ToolFiles>\n"
+      ;
+    }
 }
 
 

+ 96 - 0
Source/cmVS10MASMFlagTable.h

@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS10MASMFlagTable[] =
+{
+
+  //Enum Properties
+  {"PreserveIdentifierCase", "",
+   "Default", "0", 0},
+  {"PreserveIdentifierCase", "/Cp",
+   "Preserves Identifier Case (/Cp)", "1", 0},
+  {"PreserveIdentifierCase", "/Cu",
+   "Maps all identifiers to upper case. (/Cu)", "2", 0},
+  {"PreserveIdentifierCase", "/Cx",
+   "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+  {"WarningLevel", "/W0",
+   "Warning Level 0 (/W0)", "0", 0},
+  {"WarningLevel", "/W1",
+   "Warning Level 1 (/W1)", "1", 0},
+  {"WarningLevel", "/W2",
+   "Warning Level 2 (/W2)", "2", 0},
+  {"WarningLevel", "/W3",
+   "Warning Level 3 (/W3)", "3", 0},
+
+  {"PackAlignmentBoundary", "",
+   "Default", "0", 0},
+  {"PackAlignmentBoundary", "/Zp1",
+   "One Byte Boundary (/Zp1)", "1", 0},
+  {"PackAlignmentBoundary", "/Zp2",
+   "Two Byte Boundary (/Zp2)", "2", 0},
+  {"PackAlignmentBoundary", "/Zp4",
+   "Four Byte Boundary (/Zp4)", "3", 0},
+  {"PackAlignmentBoundary", "/Zp8",
+   "Eight Byte Boundary (/Zp8)", "4", 0},
+  {"PackAlignmentBoundary", "/Zp16",
+   "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+  {"CallingConvention", "",
+   "Default", "0", 0},
+  {"CallingConvention", "/Gd",
+   "Use C-style Calling Convention (/Gd)", "1", 0},
+  {"CallingConvention", "/Gz",
+   "Use stdcall Calling Convention (/Gz)", "2", 0},
+  {"CallingConvention", "/Gc",
+   "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+  {"ErrorReporting", "/errorReport:prompt",
+   "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+  {"ErrorReporting", "/errorReport:queue",
+   "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+  {"ErrorReporting", "/errorReport:send",
+   "Automatically send report (/errorReport:send)", "2", 0},
+  {"ErrorReporting", "/errorReport:none",
+   "Do not send report (/errorReport:none)", "3", 0},
+
+
+  //Bool Properties
+  {"NoLogo", "/nologo", "", "true", 0},
+  {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+  {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+  {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+  {"AddFirstPassListing", "/Sf", "", "true", 0},
+  {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+  {"DisableSymbolTable", "/Sn", "", "true", 0},
+  {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+  {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+  {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+  {"GenerateDebugInformation", "/Zi", "", "true", 0},
+  {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+  {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+  //Bool Properties With Argument
+
+  //String List Properties
+  {"PreprocessorDefinitions", "/D",
+   "Preprocessor Definitions",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"IncludePaths", "/I",
+   "Include Paths",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"BrowseFile", "/FR",
+   "Generate Browse Information File",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  // Skip [AdditionalDependencies] - no command line Switch.
+
+  //String Properties
+  // Skip [Inputs] - no command line Switch.
+  {"ObjectFileName", "/Fo",
+   "Object File Name",
+   "", cmVS7FlagTable::UserValue},
+  {"AssembledCodeListingFile", "/Fl",
+   "Assembled Code Listing File",
+   "", cmVS7FlagTable::UserValue},
+  // Skip [CommandLineTemplate] - no command line Switch.
+  // Skip [ExecutionDescription] - no command line Switch.
+  // Skip [AdditionalOptions] - no command line Switch.
+  {0,0,0,0,0}
+};

+ 96 - 0
Source/cmVS11MASMFlagTable.h

@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS11MASMFlagTable[] =
+{
+
+  //Enum Properties
+  {"PreserveIdentifierCase", "",
+   "Default", "0", 0},
+  {"PreserveIdentifierCase", "/Cp",
+   "Preserves Identifier Case (/Cp)", "1", 0},
+  {"PreserveIdentifierCase", "/Cu",
+   "Maps all identifiers to upper case. (/Cu)", "2", 0},
+  {"PreserveIdentifierCase", "/Cx",
+   "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+  {"WarningLevel", "/W0",
+   "Warning Level 0 (/W0)", "0", 0},
+  {"WarningLevel", "/W1",
+   "Warning Level 1 (/W1)", "1", 0},
+  {"WarningLevel", "/W2",
+   "Warning Level 2 (/W2)", "2", 0},
+  {"WarningLevel", "/W3",
+   "Warning Level 3 (/W3)", "3", 0},
+
+  {"PackAlignmentBoundary", "",
+   "Default", "0", 0},
+  {"PackAlignmentBoundary", "/Zp1",
+   "One Byte Boundary (/Zp1)", "1", 0},
+  {"PackAlignmentBoundary", "/Zp2",
+   "Two Byte Boundary (/Zp2)", "2", 0},
+  {"PackAlignmentBoundary", "/Zp4",
+   "Four Byte Boundary (/Zp4)", "3", 0},
+  {"PackAlignmentBoundary", "/Zp8",
+   "Eight Byte Boundary (/Zp8)", "4", 0},
+  {"PackAlignmentBoundary", "/Zp16",
+   "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+  {"CallingConvention", "",
+   "Default", "0", 0},
+  {"CallingConvention", "/Gd",
+   "Use C-style Calling Convention (/Gd)", "1", 0},
+  {"CallingConvention", "/Gz",
+   "Use stdcall Calling Convention (/Gz)", "2", 0},
+  {"CallingConvention", "/Gc",
+   "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+  {"ErrorReporting", "/errorReport:prompt",
+   "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+  {"ErrorReporting", "/errorReport:queue",
+   "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+  {"ErrorReporting", "/errorReport:send",
+   "Automatically send report (/errorReport:send)", "2", 0},
+  {"ErrorReporting", "/errorReport:none",
+   "Do not send report (/errorReport:none)", "3", 0},
+
+
+  //Bool Properties
+  {"NoLogo", "/nologo", "", "true", 0},
+  {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+  {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+  {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+  {"AddFirstPassListing", "/Sf", "", "true", 0},
+  {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+  {"DisableSymbolTable", "/Sn", "", "true", 0},
+  {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+  {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+  {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+  {"GenerateDebugInformation", "/Zi", "", "true", 0},
+  {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+  {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+  //Bool Properties With Argument
+
+  //String List Properties
+  {"PreprocessorDefinitions", "/D",
+   "Preprocessor Definitions",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"IncludePaths", "/I",
+   "Include Paths",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"BrowseFile", "/FR",
+   "Generate Browse Information File",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  // Skip [AdditionalDependencies] - no command line Switch.
+
+  //String Properties
+  // Skip [Inputs] - no command line Switch.
+  {"ObjectFileName", "/Fo",
+   "Object File Name",
+   "", cmVS7FlagTable::UserValue},
+  {"AssembledCodeListingFile", "/Fl",
+   "Assembled Code Listing File",
+   "", cmVS7FlagTable::UserValue},
+  // Skip [CommandLineTemplate] - no command line Switch.
+  // Skip [ExecutionDescription] - no command line Switch.
+  // Skip [AdditionalOptions] - no command line Switch.
+  {0,0,0,0,0}
+};

+ 96 - 0
Source/cmVS12MASMFlagTable.h

@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS12MASMFlagTable[] =
+{
+
+  //Enum Properties
+  {"PreserveIdentifierCase", "",
+   "Default", "0", 0},
+  {"PreserveIdentifierCase", "/Cp",
+   "Preserves Identifier Case (/Cp)", "1", 0},
+  {"PreserveIdentifierCase", "/Cu",
+   "Maps all identifiers to upper case. (/Cu)", "2", 0},
+  {"PreserveIdentifierCase", "/Cx",
+   "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+  {"WarningLevel", "/W0",
+   "Warning Level 0 (/W0)", "0", 0},
+  {"WarningLevel", "/W1",
+   "Warning Level 1 (/W1)", "1", 0},
+  {"WarningLevel", "/W2",
+   "Warning Level 2 (/W2)", "2", 0},
+  {"WarningLevel", "/W3",
+   "Warning Level 3 (/W3)", "3", 0},
+
+  {"PackAlignmentBoundary", "",
+   "Default", "0", 0},
+  {"PackAlignmentBoundary", "/Zp1",
+   "One Byte Boundary (/Zp1)", "1", 0},
+  {"PackAlignmentBoundary", "/Zp2",
+   "Two Byte Boundary (/Zp2)", "2", 0},
+  {"PackAlignmentBoundary", "/Zp4",
+   "Four Byte Boundary (/Zp4)", "3", 0},
+  {"PackAlignmentBoundary", "/Zp8",
+   "Eight Byte Boundary (/Zp8)", "4", 0},
+  {"PackAlignmentBoundary", "/Zp16",
+   "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+  {"CallingConvention", "",
+   "Default", "0", 0},
+  {"CallingConvention", "/Gd",
+   "Use C-style Calling Convention (/Gd)", "1", 0},
+  {"CallingConvention", "/Gz",
+   "Use stdcall Calling Convention (/Gz)", "2", 0},
+  {"CallingConvention", "/Gc",
+   "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+  {"ErrorReporting", "/errorReport:prompt",
+   "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+  {"ErrorReporting", "/errorReport:queue",
+   "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+  {"ErrorReporting", "/errorReport:send",
+   "Automatically send report (/errorReport:send)", "2", 0},
+  {"ErrorReporting", "/errorReport:none",
+   "Do not send report (/errorReport:none)", "3", 0},
+
+
+  //Bool Properties
+  {"NoLogo", "/nologo", "", "true", 0},
+  {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+  {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+  {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+  {"AddFirstPassListing", "/Sf", "", "true", 0},
+  {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+  {"DisableSymbolTable", "/Sn", "", "true", 0},
+  {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+  {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+  {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+  {"GenerateDebugInformation", "/Zi", "", "true", 0},
+  {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+  {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+  //Bool Properties With Argument
+
+  //String List Properties
+  {"PreprocessorDefinitions", "/D",
+   "Preprocessor Definitions",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"IncludePaths", "/I",
+   "Include Paths",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"BrowseFile", "/FR",
+   "Generate Browse Information File",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  // Skip [AdditionalDependencies] - no command line Switch.
+
+  //String Properties
+  // Skip [Inputs] - no command line Switch.
+  {"ObjectFileName", "/Fo",
+   "Object File Name",
+   "", cmVS7FlagTable::UserValue},
+  {"AssembledCodeListingFile", "/Fl",
+   "Assembled Code Listing File",
+   "", cmVS7FlagTable::UserValue},
+  // Skip [CommandLineTemplate] - no command line Switch.
+  // Skip [ExecutionDescription] - no command line Switch.
+  // Skip [AdditionalOptions] - no command line Switch.
+  {0,0,0,0,0}
+};

+ 96 - 0
Source/cmVS14MASMFlagTable.h

@@ -0,0 +1,96 @@
+static cmVS7FlagTable cmVS14MASMFlagTable[] =
+{
+
+  //Enum Properties
+  {"PreserveIdentifierCase", "",
+   "Default", "0", 0},
+  {"PreserveIdentifierCase", "/Cp",
+   "Preserves Identifier Case (/Cp)", "1", 0},
+  {"PreserveIdentifierCase", "/Cu",
+   "Maps all identifiers to upper case. (/Cu)", "2", 0},
+  {"PreserveIdentifierCase", "/Cx",
+   "Preserves case in public and extern symbols. (/Cx)", "3", 0},
+
+  {"WarningLevel", "/W0",
+   "Warning Level 0 (/W0)", "0", 0},
+  {"WarningLevel", "/W1",
+   "Warning Level 1 (/W1)", "1", 0},
+  {"WarningLevel", "/W2",
+   "Warning Level 2 (/W2)", "2", 0},
+  {"WarningLevel", "/W3",
+   "Warning Level 3 (/W3)", "3", 0},
+
+  {"PackAlignmentBoundary", "",
+   "Default", "0", 0},
+  {"PackAlignmentBoundary", "/Zp1",
+   "One Byte Boundary (/Zp1)", "1", 0},
+  {"PackAlignmentBoundary", "/Zp2",
+   "Two Byte Boundary (/Zp2)", "2", 0},
+  {"PackAlignmentBoundary", "/Zp4",
+   "Four Byte Boundary (/Zp4)", "3", 0},
+  {"PackAlignmentBoundary", "/Zp8",
+   "Eight Byte Boundary (/Zp8)", "4", 0},
+  {"PackAlignmentBoundary", "/Zp16",
+   "Sixteen Byte Boundary (/Zp16)", "5", 0},
+
+  {"CallingConvention", "",
+   "Default", "0", 0},
+  {"CallingConvention", "/Gd",
+   "Use C-style Calling Convention (/Gd)", "1", 0},
+  {"CallingConvention", "/Gz",
+   "Use stdcall Calling Convention (/Gz)", "2", 0},
+  {"CallingConvention", "/Gc",
+   "Use Pascal Calling Convention (/Gc)", "3", 0},
+
+  {"ErrorReporting", "/errorReport:prompt",
+   "Prompt to send report immediately (/errorReport:prompt)", "0", 0},
+  {"ErrorReporting", "/errorReport:queue",
+   "Prompt to send report at the next logon (/errorReport:queue)", "1", 0},
+  {"ErrorReporting", "/errorReport:send",
+   "Automatically send report (/errorReport:send)", "2", 0},
+  {"ErrorReporting", "/errorReport:none",
+   "Do not send report (/errorReport:none)", "3", 0},
+
+
+  //Bool Properties
+  {"NoLogo", "/nologo", "", "true", 0},
+  {"GeneratePreprocessedSourceListing", "/EP", "", "true", 0},
+  {"ListAllAvailableInformation", "/Sa", "", "true", 0},
+  {"UseSafeExceptionHandlers", "/safeseh", "", "true", 0},
+  {"AddFirstPassListing", "/Sf", "", "true", 0},
+  {"EnableAssemblyGeneratedCodeListing", "/Sg", "", "true", 0},
+  {"DisableSymbolTable", "/Sn", "", "true", 0},
+  {"EnableFalseConditionalsInListing", "/Sx", "", "true", 0},
+  {"TreatWarningsAsErrors", "/WX", "", "true", 0},
+  {"MakeAllSymbolsPublic", "/Zf", "", "true", 0},
+  {"GenerateDebugInformation", "/Zi", "", "true", 0},
+  {"EnableMASM51Compatibility", "/Zm", "", "true", 0},
+  {"PerformSyntaxCheckOnly", "/Zs", "", "true", 0},
+
+  //Bool Properties With Argument
+
+  //String List Properties
+  {"PreprocessorDefinitions", "/D",
+   "Preprocessor Definitions",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"IncludePaths", "/I",
+   "Include Paths",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  {"BrowseFile", "/FR",
+   "Generate Browse Information File",
+   "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+  // Skip [AdditionalDependencies] - no command line Switch.
+
+  //String Properties
+  // Skip [Inputs] - no command line Switch.
+  {"ObjectFileName", "/Fo",
+   "Object File Name",
+   "", cmVS7FlagTable::UserValue},
+  {"AssembledCodeListingFile", "/Fl",
+   "Assembled Code Listing File",
+   "", cmVS7FlagTable::UserValue},
+  // Skip [CommandLineTemplate] - no command line Switch.
+  // Skip [ExecutionDescription] - no command line Switch.
+  // Skip [AdditionalOptions] - no command line Switch.
+  {0,0,0,0,0}
+};

+ 93 - 1
Source/cmVisualStudio10TargetGenerator.cxx

@@ -24,18 +24,22 @@
 #include "cmVS10RCFlagTable.h"
 #include "cmVS10LinkFlagTable.h"
 #include "cmVS10LibFlagTable.h"
+#include "cmVS10MASMFlagTable.h"
 #include "cmVS11CLFlagTable.h"
 #include "cmVS11RCFlagTable.h"
 #include "cmVS11LinkFlagTable.h"
 #include "cmVS11LibFlagTable.h"
+#include "cmVS11MASMFlagTable.h"
 #include "cmVS12CLFlagTable.h"
 #include "cmVS12RCFlagTable.h"
 #include "cmVS12LinkFlagTable.h"
 #include "cmVS12LibFlagTable.h"
+#include "cmVS12MASMFlagTable.h"
 #include "cmVS14CLFlagTable.h"
 #include "cmVS14RCFlagTable.h"
 #include "cmVS14LinkFlagTable.h"
 #include "cmVS14LibFlagTable.h"
+#include "cmVS14MASMFlagTable.h"
 
 #include <cmsys/auto_ptr.hxx>
 
@@ -111,6 +115,24 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetLinkFlagTable() const
   return 0;
 }
 
+cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetMasmFlagTable() const
+{
+  if(this->MSTools)
+    {
+    cmLocalVisualStudioGenerator::VSVersion
+      v = this->LocalGenerator->GetVersion();
+    if(v >= cmLocalVisualStudioGenerator::VS14)
+      { return cmVS14MASMFlagTable; }
+    else if(v >= cmLocalVisualStudioGenerator::VS12)
+      { return cmVS12MASMFlagTable; }
+    else if(v == cmLocalVisualStudioGenerator::VS11)
+      { return cmVS11MASMFlagTable; }
+    else
+      { return cmVS10MASMFlagTable; }
+    }
+  return 0;
+}
+
 static std::string cmVS10EscapeXML(std::string arg)
 {
   cmSystemTools::ReplaceString(arg, "&", "&amp;");
@@ -251,6 +273,10 @@ void cmVisualStudio10TargetGenerator::Generate()
       {
       return;
       }
+    if(!this->ComputeMasmOptions())
+      {
+      return;
+      }
     if(!this->ComputeLinkOptions())
       {
       return;
@@ -1192,7 +1218,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
       {
       tool = "ClCompile";
       }
-    else if (lang == "ASM_NASM" &&
+    else if (lang == "ASM_MASM" &&
              this->GlobalGenerator->IsMasmEnabled())
       {
       tool = "MASM";
@@ -1715,6 +1741,71 @@ WriteRCOptions(std::string const& configName,
   this->WriteString("</ResourceCompile>\n", 2);
 }
 
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeMasmOptions()
+{
+  if(!this->GlobalGenerator->IsMasmEnabled())
+    {
+    return true;
+    }
+  std::vector<std::string> const* configs =
+    this->GlobalGenerator->GetConfigurations();
+  for(std::vector<std::string>::const_iterator i = configs->begin();
+      i != configs->end(); ++i)
+    {
+    if(!this->ComputeMasmOptions(*i))
+      {
+      return false;
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
+  std::string const& configName)
+{
+  cmsys::auto_ptr<Options> pOptions(
+    new Options(this->LocalGenerator, Options::MasmCompiler,
+                this->GetMasmFlagTable()));
+  Options& masmOptions = *pOptions;
+
+  std::string CONFIG = cmSystemTools::UpperCase(configName);
+  std::string configFlagsVar = std::string("CMAKE_ASM_MASM_FLAGS_") + CONFIG;
+  std::string flags =
+      std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS")) +
+      std::string(" ") +
+      std::string(this->Makefile->GetSafeDefinition(configFlagsVar));
+
+  masmOptions.Parse(flags.c_str());
+  this->MasmOptions[configName] = pOptions.release();
+  return true;
+}
+
+void cmVisualStudio10TargetGenerator::
+WriteMasmOptions(std::string const& configName,
+                 std::vector<std::string> const& includes)
+{
+  if(!this->MSTools || !this->GlobalGenerator->IsMasmEnabled())
+    {
+    return;
+    }
+  this->WriteString("<MASM>\n", 2);
+
+  // Preprocessor definitions and includes are shared with clOptions.
+  Options& clOptions = *(this->ClOptions[configName]);
+  clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
+                                          "\n", "ASM_MASM");
+
+  Options& masmOptions = *(this->MasmOptions[configName]);
+  masmOptions.AppendFlag("IncludePaths", includes);
+  masmOptions.AppendFlag("IncludePaths", "%(IncludePaths)");
+  masmOptions.OutputFlagMap(*this->BuildFileStream, "      ");
+  masmOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
+
+  this->WriteString("</MASM>\n", 2);
+}
+
 
 void
 cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
@@ -2059,6 +2150,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
       this->WriteClOptions(*i, includes);
       //    output rc compile flags <ResourceCompile></ResourceCompile>
       this->WriteRCOptions(*i, includes);
+      this->WriteMasmOptions(*i, includes);
       }
     //    output midl flags       <Midl></Midl>
     this->WriteMidlOptions(*i, includes);

+ 6 - 0
Source/cmVisualStudio10TargetGenerator.h

@@ -78,6 +78,10 @@ private:
   bool ComputeRcOptions(std::string const& config);
   void WriteRCOptions(std::string const& config,
                       std::vector<std::string> const & includes);
+  bool ComputeMasmOptions();
+  bool ComputeMasmOptions(std::string const& config);
+  void WriteMasmOptions(std::string const& config,
+                        std::vector<std::string> const& includes);
   bool ComputeLinkOptions();
   bool ComputeLinkOptions(std::string const& config);
   void WriteLinkOptions(std::string const& config);
@@ -109,12 +113,14 @@ private:
   cmIDEFlagTable const* GetRcFlagTable() const;
   cmIDEFlagTable const* GetLibFlagTable() const;
   cmIDEFlagTable const* GetLinkFlagTable() const;
+  cmIDEFlagTable const* GetMasmFlagTable() const;
 
 private:
   typedef cmVisualStudioGeneratorOptions Options;
   typedef std::map<std::string, Options*> OptionsMap;
   OptionsMap ClOptions;
   OptionsMap RcOptions;
+  OptionsMap MasmOptions;
   OptionsMap LinkOptions;
   std::string PathToVcxproj;
   cmTarget* Target;

+ 1 - 0
Source/cmVisualStudioGeneratorOptions.h

@@ -28,6 +28,7 @@ public:
   {
     Compiler,
     ResourceCompiler,
+    MasmCompiler,
     Linker,
     FortranCompiler
   };

+ 8 - 0
Tests/CMakeLists.txt

@@ -1679,6 +1679,14 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MFC")
   endif()
 
+  if(MSVC AND NOT MSVC_VERSION LESS 1310
+     AND NOT CMAKE_GENERATOR MATCHES "Visual Studio [67]( |$)"
+     AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio [89]( |$)"
+          OR CMAKE_SIZEOF_VOID_P EQUAL 4)
+      )
+    ADD_TEST_MACRO(VSMASM VSMASM)
+  endif()
+
   if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
     if(NOT MSVC60)
       ADD_TEST_MACRO(SBCS SBCS)

+ 10 - 0
Tests/VSMASM/CMakeLists.txt

@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(VSMASM C ASM_MASM)
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+  add_definitions(-DTESTx64)
+else()
+  add_definitions(-DTESTi386)
+  set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /safeseh")
+endif()
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+add_executable(VSMASM main.c foo.asm)

+ 7 - 0
Tests/VSMASM/foo.asm

@@ -0,0 +1,7 @@
+ifndef TESTx64
+.386
+.model flat, c
+endif
+.code
+include <foo-proc.asm>
+end

+ 4 - 0
Tests/VSMASM/include/foo-proc.asm

@@ -0,0 +1,4 @@
+foo proc public
+  mov eax,0
+  ret
+foo endp

+ 2 - 0
Tests/VSMASM/main.c

@@ -0,0 +1,2 @@
+extern int foo(void);
+int main(void) { return foo(); }