diff --git a/docs/classes.rst b/docs/classes.rst
index 21117b6..4a81632 100644
--- a/docs/classes.rst
+++ b/docs/classes.rst
@@ -101,6 +101,26 @@ visual_studio.BuildVisualStudioFile
.. doxygenclass:: makeprojects::visual_studio::BuildVisualStudioFile
:members:
+visual_studio.VS2003XML
+^^^^^^^^^^^^^^^^^^^^^^^
+.. doxygenclass:: makeprojects::visual_studio::VS2003XML
+ :members:
+
+visual_studio.VS2003Tool
+^^^^^^^^^^^^^^^^^^^^^^^^
+.. doxygenclass:: makeprojects::visual_studio::VS2003Tool
+ :members:
+
+visual_studio.VCCLCompilerTool
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. doxygenclass:: makeprojects::visual_studio::VCCLCompilerTool
+ :members:
+
+visual_studio.VCCLCompilerToolFile
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. doxygenclass:: makeprojects::visual_studio::VCCLCompilerToolFile
+ :members:
+
Watcom
------
diff --git a/makeprojects/validators.py b/makeprojects/validators.py
index 24d60da..72a91f2 100644
--- a/makeprojects/validators.py
+++ b/makeprojects/validators.py
@@ -439,10 +439,10 @@ def validate(key, configuration, fallback=None,
@staticmethod
def vs_validate(key, configuration, fallback=None,
- options_key=None, options=None):
+ options_key=None, options=None, prefix=None):
"""
Check if there is an override with a vs_ prefix.
- Check if the configuration has a key of \"vs_\" + key in the
+ Check if the configuration has a key of \"vs_\" + prefix + key in the
configuration and if not found or None, use the key as is.
Args:
@@ -451,11 +451,18 @@ def vs_validate(key, configuration, fallback=None,
fallback: Value to use in case there is no override.
options_key: Attribute to scan for commmand line options
options: Iterable with options / Value pairs
+ prefix: String to insert after "vs_"
Returns:
None or VSBooleanProperty instance
"""
- value = configuration.get_chained_value("vs_" + key)
+ # Insert the optional prefix
+ new_key = "vs_"
+ if prefix:
+ new_key = new_key + prefix
+ new_key = new_key + key
+
+ value = configuration.get_chained_value(new_key)
if value is None:
return VSBooleanProperty.validate(
key, configuration, fallback, options_key, options)
@@ -590,6 +597,37 @@ def get_value(self):
########################################
+ @staticmethod
+ def vs_validate(key, configuration, fallback=None, prefix=None):
+ """
+ Check if there is an override with a vs_ prefix.
+ @details
+ Check if the configuration has a key of \"vs_\" + prefix + key in the
+ configuration and if not found or None, use the fallback as is.
+
+ Args:
+ key: Name of the XML attribute key
+ configuration: configuration to scan for an override
+ fallback: Value to use in case there is no override.
+ prefix: String to insert after "vs_"
+
+ Returns:
+ VSStringProperty instance
+ """
+
+ # Insert the optional prefix
+ new_key = "vs_"
+ if prefix:
+ new_key = new_key + prefix
+ new_key = new_key + key
+
+ value = configuration.get_chained_value(new_key)
+ if value is None:
+ return VSStringProperty(key, fallback)
+ return VSStringProperty(key, value)
+
+ ########################################
+
def __repr__(self):
"""
Convert to string.
diff --git a/makeprojects/visual_studio.py b/makeprojects/visual_studio.py
index 3ff5048..fc0552c 100644
--- a/makeprojects/visual_studio.py
+++ b/makeprojects/visual_studio.py
@@ -687,56 +687,184 @@ def create_deploy_script(configuration):
########################################
-# Boolean properties
+# Entries usually found in VCCLCompilerTool
-def BoolUseUnicodeResponseFiles(configuration):
+def UseUnicodeResponseFiles(configuration, prefix=None):
"""
- Entry for UseUnicodeResponseFiles
+ Create ``UseUnicodeResponseFiles`` property.
Instructs the project system to generate UNICODE response files when
spawning the librarian. Set this property to True when files in the project
have UNICODE paths.
+ Can be overridden with configuration attributes:
+
+ * ``vs_UseUnicodeResponseFiles`` for the C compiler.
+ * ``vs_LinkerUseUnicodeResponseFiles`` for the exe linker.
+ * ``vs_LibrarianUseUnicodeResponseFiles`` for the library linker.
+
Note:
- Not available on Visual Studio 2003 and earlier.
+ Not available on Visual Studio 2003 and earlier. Overrides do nothing.
+
Args:
configuration: Project configuration to scan for overrides.
+ prefix: Prefix string for override
Returns:
- None or VSBooleanProperty object.
+ validators.VSBooleanProperty object.
"""
if configuration.ide > IDETypes.vs2003:
return VSBooleanProperty.vs_validate(
- "UseUnicodeResponseFiles", configuration)
+ "UseUnicodeResponseFiles", configuration, prefix=prefix)
return None
+########################################
+
+
+def AdditionalOptions(configuration, prefix=None):
+ """
+ Create ``AdditionalOptions`` property.
+
+ List of custom compiler options as a single string. The default is an empty
+ string. Will not generate this attribute if the string is empty.
+
+ Can be overridden with configuration attributes:
+
+ * ``vs_AdditionalOptions`` for the C compiler.
+ * ``vs_LinkerAdditionalOptions`` for the exe linker.
+ * ``vs_LibrarianAdditionalOptions`` for the library linker.
+
+ Args:
+ configuration: Project configuration to scan for overrides.
+ prefix: Prefix string for override
+ Returns:
+ validators.VSStringProperty object.
+ """
+
+ return VSStringProperty.vs_validate(
+ "AdditionalOptions", configuration, prefix=prefix)
+
+########################################
+
+
+def Optimization(configuration, fallback=None):
+ """
+ Create ``Optimization`` property.
+
+ Set the level of code optimization for the C compiler.
+
+ Compiler switches /Od, /O1, /O2, /Ox
+
+ Can be overridden with configuration attribute
+ ``vs_Optimization`` for the C compiler.
+
+ Acceptable inputs are:
+
+ * "/Od" / "-Od" / "Disabled"
+ * "/O1" / "-O1" / "Minimize Size"
+ * "/O2" / "-O2" / "Maximize Speed"
+ * "/Ox" / "-Ox" / "Full Optimization" / "x"
+ * "Custom" (This disables emitting a command switch)
+ * 0 through 4
+
+ Args:
+ configuration: Project configuration to scan for overrides.
+ fallback: Default value to use
+ Returns:
+ validators.VSEnumProperty object.
+ """
+
+ # Was there an override?
+ value = configuration.get_chained_value("vs_Optimization")
+ if value is not None:
+ fallback = value
-def BoolGlobalOptimizations(configuration):
- """ GlobalOptimizations
+ # The settings are the same on 2003, 2005, and 2008
+ return VSEnumProperty(
+ "Optimization",
+ fallback,
+ (("/Od", "-Od", "Disabled"),
+ ("/O1", "-O1", "Minimize Size"),
+ ("/O2", "-O2", "Maximize Speed"),
+ ("/Ox", "-Ox", "Full Optimization", "x"),
+ "Custom"))
+
+########################################
+
+
+def GlobalOptimizations(configuration, fallback=None):
+ """
+ Create ``GlobalOptimizations`` property.
Enables global optimizations incompatible with all ``Runtime Checks``
- options and edit and continue. Also known as WholeProgramOptimizations
+ options and edit and continue. Also known as ``WholeProgramOptimizations``
on other versions of Visual Studio.
Compiler switch /Og
+ Can be overridden with configuration attribute
+ ``vs_GlobalOptimizations`` for the C compiler.
+
Note:
Only available on Visual Studio 2003
Args:
configuration: Project configuration to scan for overrides.
+ fallback: Default value to use
Returns:
- None or VSBooleanProperty object.
+ None or validators.VSBooleanProperty object.
"""
if configuration.ide is IDETypes.vs2003:
return VSBooleanProperty.vs_validate(
"GlobalOptimizations",
configuration,
- fallback=configuration.optimization,
- options_key="compiler_options",
- options=(("/Og", True),))
+ fallback=fallback)
return None
+########################################
+
+
+def InlineFunctionExpansion(configuration, fallback=None):
+ """
+ Create ``InlineFunctionExpansion`` property.
+
+ Determine how aggressive to inline code during C compilation.
+
+ Compiler switches /Ob1, /Ob2
+
+ Can be overridden with configuration attribute
+ ``vs_InlineFunctionExpansion`` for the C compiler.
+
+ Acceptable inputs are:
+
+ * "Disable"
+ * "/Ob1", "Only __inline"
+ * "/Ob2", "Any Suitable"
+ * 0 through 2
+
+ Args:
+ configuration: Project configuration to scan for overrides.
+ fallback: Default value to use
+
+ Returns:
+ validators.VSEnumProperty object.
+ """
+
+ # Was there an override?
+ value = configuration.get_chained_value("vs_InlineFunctionExpansion")
+ if value is not None:
+ fallback = value
+
+ # The settings are the same on 2003, 2005, and 2008
+ return VSEnumProperty(
+ "InlineFunctionExpansion", fallback,
+ ("Disable",
+ ("/Ob1", "Only __inline"),
+ ("/Ob2", "Any Suitable")))
+
+
+# Boolean properties
+
def BoolRegisterOutput(configuration):
""" RegisterOutput
@@ -1854,11 +1982,6 @@ def StringName(default):
return VSStringProperty("Name", fallback=default)
-def StringAdditionalOptions():
- """ List of custom compiler options as a single string """
- return VSStringProperty("AdditionalOptions")
-
-
def StringPrecompiledHeaderThrough():
""" Text header file for precompilation """
return VSStringProperty("PrecompiledHeaderThrough")
@@ -1965,11 +2088,11 @@ class VS2003XML():
Theses are examples of XML fragments this class exports.
- @code{.unparsed}
-
-
-
+ ```xml
+
+
+
@@ -1978,7 +2101,7 @@ class VS2003XML():
- @endcode
+ ```
Attributes:
name: Name of this XML chunk.
@@ -2130,7 +2253,7 @@ def reset_attribute(self, name):
def generate(self, line_list=None, indent=0, ide=None):
"""
Generate the text lines for this XML element.
-
+ @details
There is a slight difference between Visual Studio 2003
and 2005/2008 on how tags are closed. The argument ``ide``
is used to flag with close format to use.
@@ -2143,9 +2266,7 @@ def generate(self, line_list=None, indent=0, ide=None):
line_list with all lines appended to it.
"""
- # Too many branches
- # Too many statements
- # pylint: disable=R0912,R0915
+ # pylint: disable=too-many-branches
# Create the default
if line_list is None:
@@ -2155,7 +2276,7 @@ def generate(self, line_list=None, indent=0, ide=None):
ide = IDETypes.vs2008
# Determine the indentation
- # vs2003 uses tabs
+ # VS2003 uses tabs
tabs = "\t" * indent
# Special case, if no attributes, don't allow XML
@@ -2168,6 +2289,7 @@ def generate(self, line_list=None, indent=0, ide=None):
if value is not None:
attributes.append((item.name, value))
+ elements = self.elements
if attributes:
# Output tag with attributes and support "/>" closing
@@ -2176,18 +2298,18 @@ def generate(self, line_list=None, indent=0, ide=None):
# VS2003 has upper case booleans
if ide is IDETypes.vs2003:
- if value == "true":
- value = "TRUE"
- elif value == "false":
- value = "FALSE"
+ if value in ("true", "false"):
+ value = value.upper()
- # VS 2003 doesn't encode CR
+ # If the string has CR, VS2003 doesn't xml encode it,
+ # so it's in the string literally
+ # VS2005 and VS2008 use
+
+ # Encode special characters
value = escape_xml_attribute(value)
- if ide is IDETypes.vs2003:
- cr_fixup = "\n"
- else:
- # VS 2005 and 2008 require cr/lf
- cr_fixup = "
"
+
+ # If there's a CR, it's
, so convert it
+ cr_fixup = "\n" if ide is IDETypes.vs2003 else "
"
value = value.replace("
", cr_fixup)
# Create the line (Might have line feeds)
@@ -2196,36 +2318,43 @@ def generate(self, line_list=None, indent=0, ide=None):
escape_xml_cdata(attribute[0]),
value)
- # Convert to line(s)
+ # Convert to line(s) and append
+ # This only happens on VS2003, the others always have one line
line_list.extend(item.split("\n"))
# Check if /> closing is disabled
- if not self.elements and not self.force_pair:
+ force_pair = self.force_pair
+ if not elements and not force_pair:
+ # 2003 closes on the current line, which makes the xml
+ # compact, where 2005 and 2008 are on the next line
if ide is IDETypes.vs2003:
line_list[-1] = line_list[-1] + "/>"
else:
- line_list.append("{}/>".format(tabs))
+ line_list.append(tabs + "/>")
return line_list
- # Close the open tag
+ # Close the open tag on the same line with 2003,
+ # next line on 2005/2008
if ide is IDETypes.vs2003:
line_list[-1] = line_list[-1] + ">"
else:
- line_list.append("{}\t>".format(tabs))
+ line_list.append(tabs + "\t>")
else:
+
+ # No elements? Close on the same line
line_list[-1] = line_list[-1] + ">"
# Output the embedded elements
- for element in self.elements:
+ for element in elements:
element.generate(line_list, indent=indent + 1, ide=ide)
# Close the current element
- line_list.append("{0}{1}>".format(tabs, escape_xml_cdata(self.name)))
+ line_list.append(tabs + "" + escape_xml_cdata(self.name) + ">")
return line_list
def __repr__(self):
"""
- Convert the solultion record into a human readable description
+ Convert the solution record into a human readable description
Returns:
Human readable string or None if the solution is invalid
@@ -2287,10 +2416,6 @@ def __init__(self, configuration):
configuration: Configuration record to extract defaults.
"""
- # Too many branches
- # Too many statements
- # pylint: disable=R0912,R0915
-
self.configuration = configuration
# Set the tag
@@ -2305,34 +2430,25 @@ def __init__(self, configuration):
# Attributes are added in the same order they are written
# in Visual Studio
- # List of custom compiler options as a single string
- self.add_default(StringAdditionalOptions())
+ # Unicode response files (Only on 2005/2008)
+ self.add_default(UseUnicodeResponseFiles(configuration))
- # Unicode response files
- self.add_default(BoolUseUnicodeResponseFiles(configuration))
+ # List of custom compiler options as a single string
+ self.add_default(AdditionalOptions(configuration))
# Optimizations
- default = "/Ox" if optimization else "/Od"
- self.add_default(
- VSEnumProperty(
- "Optimization", default,
- (("/Od", "Disabled"),
- ("/O1", "Minimize Size"),
- ("/O2", "Maximize Speed"),
- ("/Ox", "Full Optimization"),
- "Custom")))
+ item = "Full Optimization" if optimization else "Disabled"
+ self.add_default(Optimization(configuration, item))
# Global optimizations (2003 only)
- self.add_default(BoolGlobalOptimizations(configuration))
+ self.add_default(
+ GlobalOptimizations(
+ configuration,
+ configuration.link_time_code_generation))
# Inline functions
- default = "/Ob2" if optimization else None
- self.add_default(
- VSEnumProperty(
- "InlineFunctionExpansion", default,
- ("Disable",
- ("/Ob1", "Only __inline"),
- ("/Ob2", "Any Suitable"))))
+ item = "Any Suitable" if optimization else None
+ self.add_default(InlineFunctionExpansion(configuration, item))
# Enable intrinsics
self.add_default(BoolEnableIntrinsicFunctions(configuration))
@@ -2769,11 +2885,11 @@ def __init__(self, configuration):
# Use the librarian for input
self.add_default(BoolUseLibraryDependencyInputs(configuration))
- # Allow unicode filenames in response files
- self.add_default(BoolUseUnicodeResponseFiles(configuration))
+ # Unicode response files (Only on 2005/2008)
+ self.add_default(UseUnicodeResponseFiles(configuration, "Linker"))
# Additional commands
- self.add_default(StringAdditionalOptions())
+ self.add_default(AdditionalOptions(configuration, "Linker"))
# Additional libraries
default = configuration.get_unique_chained_list(
@@ -3204,14 +3320,14 @@ def __init__(self, configuration):
VS2003Tool.__init__(self, "VCLibrarianTool")
- # Use unicode for responses
- self.add_default(BoolUseUnicodeResponseFiles(configuration))
+ # Unicode response files (Only on 2005/2008)
+ self.add_default(UseUnicodeResponseFiles(configuration, "Librarian"))
# Link in library dependencies
self.add_default(BoolLinkLibraryDependencies(configuration))
# Additional command lines
- self.add_default(StringAdditionalOptions())
+ self.add_default(AdditionalOptions(configuration, "Librarian"))
# Libaries to link in
default = []
@@ -4084,6 +4200,7 @@ class VS2003FileConfiguration(VS2003XML):
Attributes:
configuration: Parent configuration
+ source_file: Source code file
"""
def __init__(self, configuration, base_name, source_file):
@@ -4223,8 +4340,9 @@ def handle_vs2003_rules(self, rule_list, base_name, tool_name, tool_enums):
element_dict[item] = value
# Were there any overrides?
+ source_file = self.source_file
cmd, description, outputs = make_command(
- element_dict, self.source_file)
+ element_dict, source_file)
if cmd:
element = VS2003Tool("VCCustomBuildTool")
self.add_element(element)