diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst index ac1b14bd443..e245a0c6a5b 100644 --- a/Doc/library/imp.rst +++ b/Doc/library/imp.rst @@ -112,10 +112,16 @@ This module provides an interface to the mechanisms used to implement the .. function:: acquire_lock() - Acquires the interpreter's import lock for the current thread. This lock should + Acquire the interpreter's import lock for the current thread. This lock should be used by import hooks to ensure thread-safety when importing modules. On platforms without threads, this function does nothing. + Once a thread has acquired the import lock, the same thread may acquire it + again without blocking; the thread must release it once for each time it has + acquired it. + + On platforms without threads, this function does nothing. + .. function:: release_lock() diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 9e06a222091..ce6aab3e5a8 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1458,159 +1458,160 @@ The constructors for both classes work the same: sets, the inner sets must be :class:`frozenset` objects. If *iterable* is not specified, a new empty set is returned. -Instances of :class:`set` and :class:`frozenset` provide the following -operations: + Instances of :class:`set` and :class:`frozenset` provide the following + operations: -.. describe:: len(s) + .. describe:: len(s) - Return the cardinality of set *s*. + Return the cardinality of set *s*. -.. describe:: x in s + .. describe:: x in s - Test *x* for membership in *s*. + Test *x* for membership in *s*. -.. describe:: x not in s + .. describe:: x not in s - Test *x* for non-membership in *s*. + Test *x* for non-membership in *s*. -.. method:: set.isdisjoint(other) + .. method:: isdisjoint(other) - Return True if the set has no elements in common with *other*. - Sets are disjoint if and only if their interesection is the empty set. + Return True if the set has no elements in common with *other*. Sets are + disjoint if and only if their interesection is the empty set. -.. method:: set.issubset(other) - set <= other + .. method:: issubset(other) + set <= other - Test whether every element in the set is in *other*. + Test whether every element in the set is in *other*. -.. method:: set < other + .. method:: set < other - Test whether the set is a true subset of *other*, that is, - ``set <= other and set != other``. + Test whether the set is a true subset of *other*, that is, + ``set <= other and set != other``. -.. method:: set.issuperset(other) - set >= other + .. method:: issuperset(other) + set >= other - Test whether every element in *other* is in the set. + Test whether every element in *other* is in the set. -.. method:: set > other + .. method:: set > other - Test whether the set is a true superset of *other*, that is, - ``set >= other and set != other``. + Test whether the set is a true superset of *other*, that is, ``set >= + other and set != other``. -.. method:: set.union(other) - set | other + .. method:: union(other) + set | other - Return a new set with elements from both sets. + Return a new set with elements from both sets. -.. method:: set.intersection(other) - set & other + .. method:: intersection(other) + set & other - Return a new set with elements common to both sets. + Return a new set with elements common to both sets. -.. method:: set.difference(other) - set - other + .. method:: difference(other) + set - other - Return a new set with elements in the set that are not in *other*. + Return a new set with elements in the set that are not in *other*. -.. method:: set.symmetric_difference(other) - set ^ other + .. method:: symmetric_difference(other) + set ^ other - Return a new set with elements in either the set or *other* but not both. + Return a new set with elements in either the set or *other* but not both. -.. method:: set.copy() + .. method:: copy() - Return a new set with a shallow copy of *s*. + Return a new set with a shallow copy of *s*. -Note, the non-operator versions of :meth:`union`, :meth:`intersection`, -:meth:`difference`, and :meth:`symmetric_difference`, :meth:`issubset`, and -:meth:`issuperset` methods will accept any iterable as an argument. In -contrast, their operator based counterparts require their arguments to be sets. -This precludes error-prone constructions like ``set('abc') & 'cbs'`` in favor of -the more readable ``set('abc').intersection('cbs')``. + Note, the non-operator versions of :meth:`union`, :meth:`intersection`, + :meth:`difference`, and :meth:`symmetric_difference`, :meth:`issubset`, and + :meth:`issuperset` methods will accept any iterable as an argument. In + contrast, their operator based counterparts require their arguments to be + sets. This precludes error-prone constructions like ``set('abc') & 'cbs'`` + in favor of the more readable ``set('abc').intersection('cbs')``. -Both :class:`set` and :class:`frozenset` support set to set comparisons. Two -sets are equal if and only if every element of each set is contained in the -other (each is a subset of the other). A set is less than another set if and -only if the first set is a proper subset of the second set (is a subset, but is -not equal). A set is greater than another set if and only if the first set is a -proper superset of the second set (is a superset, but is not equal). + Both :class:`set` and :class:`frozenset` support set to set comparisons. Two + sets are equal if and only if every element of each set is contained in the + other (each is a subset of the other). A set is less than another set if and + only if the first set is a proper subset of the second set (is a subset, but + is not equal). A set is greater than another set if and only if the first set + is a proper superset of the second set (is a superset, but is not equal). -Instances of :class:`set` are compared to instances of :class:`frozenset` based -on their members. For example, ``set('abc') == frozenset('abc')`` returns -``True`` and so does ``set('abc') in set([frozenset('abc')])``. + Instances of :class:`set` are compared to instances of :class:`frozenset` + based on their members. For example, ``set('abc') == frozenset('abc')`` + returns ``True`` and so does ``set('abc') in set([frozenset('abc')])``. -The subset and equality comparisons do not generalize to a complete ordering -function. For example, any two disjoint sets are not equal and are not subsets -of each other, so *all* of the following return ``False``: ``ab``. Accordingly, sets do not implement the :meth:`__cmp__` method. + The subset and equality comparisons do not generalize to a complete ordering + function. For example, any two disjoint sets are not equal and are not + subsets of each other, so *all* of the following return ``False``: ``ab``. Accordingly, sets do not implement the :meth:`__cmp__` + method. -Since sets only define partial ordering (subset relationships), the output of -the :meth:`list.sort` method is undefined for lists of sets. + Since sets only define partial ordering (subset relationships), the output of + the :meth:`list.sort` method is undefined for lists of sets. -Set elements, like dictionary keys, must be :term:`hashable`. + Set elements, like dictionary keys, must be :term:`hashable`. -Binary operations that mix :class:`set` instances with :class:`frozenset` return -the type of the first operand. For example: ``frozenset('ab') | set('bc')`` -returns an instance of :class:`frozenset`. + Binary operations that mix :class:`set` instances with :class:`frozenset` + return the type of the first operand. For example: ``frozenset('ab') | + set('bc')`` returns an instance of :class:`frozenset`. -The following table lists operations available for :class:`set` that do not -apply to immutable instances of :class:`frozenset`: + The following table lists operations available for :class:`set` that do not + apply to immutable instances of :class:`frozenset`: -.. method:: set.update(other) - set |= other + .. method:: update(other) + set |= other - Update the set, adding elements from *other*. + Update the set, adding elements from *other*. -.. method:: set.intersection_update(other) - set &= other + .. method:: intersection_update(other) + set &= other - Update the set, keeping only elements found in it and *other*. + Update the set, keeping only elements found in it and *other*. -.. method:: set.difference_update(other) - set -= other + .. method:: difference_update(other) + set -= other - Update the set, removing elements found in *other*. + Update the set, removing elements found in *other*. -.. method:: set.symmetric_difference_update(other) - set ^= other + .. method:: symmetric_difference_update(other) + set ^= other - Update the set, keeping only elements found in either set, but not in both. + Update the set, keeping only elements found in either set, but not in both. -.. method:: set.add(elem) + .. method:: add(elem) - Add element *elem* to the set. + Add element *elem* to the set. -.. method:: set.remove(elem) + .. method:: remove(elem) - Remove element *elem* from the set. Raises :exc:`KeyError` if *elem* is not - contained in the set. + Remove element *elem* from the set. Raises :exc:`KeyError` if *elem* is + not contained in the set. -.. method:: set.discard(elem) + .. method:: discard(elem) - Remove element *elem* from the set if it is present. + Remove element *elem* from the set if it is present. -.. method:: set.pop() + .. method:: pop() - Remove and return an arbitrary element from the set. Raises :exc:`KeyError` - if the set is empty. + Remove and return an arbitrary element from the set. Raises + :exc:`KeyError` if the set is empty. -.. method:: set.clear() + .. method:: clear() - Remove all elements from the set. + Remove all elements from the set. -Note, the non-operator versions of the :meth:`update`, -:meth:`intersection_update`, :meth:`difference_update`, and -:meth:`symmetric_difference_update` methods will accept any iterable as an -argument. + Note, the non-operator versions of the :meth:`update`, + :meth:`intersection_update`, :meth:`difference_update`, and + :meth:`symmetric_difference_update` methods will accept any iterable as an + argument. -Note, the *elem* argument to the :meth:`__contains__`, :meth:`remove`, and -:meth:`discard` methods may be a set. To support searching for an equivalent -frozenset, the *elem* set is temporarily mutated during the search and then -restored. During the search, the *elem* set should not be read or mutated -since it does not have a meaningful value. + Note, the *elem* argument to the :meth:`__contains__`, :meth:`remove`, and + :meth:`discard` methods may be a set. To support searching for an equivalent + frozenset, the *elem* set is temporarily mutated during the search and then + restored. During the search, the *elem* set should not be read or mutated + since it does not have a meaningful value. .. _typesmapping: @@ -1674,108 +1675,109 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: others work with any valid keys. -These are the operations that dictionaries support (and therefore, custom mapping -types should support too): + These are the operations that dictionaries support (and therefore, custom + mapping types should support too): -.. describe:: len(d) + .. describe:: len(d) - Return the number of items in the dictionary *d*. + Return the number of items in the dictionary *d*. -.. describe:: d[key] + .. describe:: d[key] - Return the item of *d* with key *key*. Raises a :exc:`KeyError` if *key* is - not in the map. - - If a subclass of dict defines a method :meth:`__missing__`, if the key *key* - is not present, the ``d[key]`` operation calls that method with the key *key* - as argument. The ``d[key]`` operation then returns or raises whatever is - returned or raised by the ``__missing__(key)`` call if the key is not - present. No other operations or methods invoke :meth:`__missing__`. If - :meth:`__missing__` is not defined, :exc:`KeyError` is raised. - :meth:`__missing__` must be a method; it cannot be an instance variable. For - an example, see :class:`collections.defaultdict`. + Return the item of *d* with key *key*. Raises a :exc:`KeyError` if *key* is + not in the map. + + If a subclass of dict defines a method :meth:`__missing__`, if the key *key* + is not present, the ``d[key]`` operation calls that method with the key *key* + as argument. The ``d[key]`` operation then returns or raises whatever is + returned or raised by the ``__missing__(key)`` call if the key is not + present. No other operations or methods invoke :meth:`__missing__`. If + :meth:`__missing__` is not defined, :exc:`KeyError` is raised. + :meth:`__missing__` must be a method; it cannot be an instance variable. For + an example, see :class:`collections.defaultdict`. -.. describe:: d[key] = value + .. describe:: d[key] = value - Set ``d[key]`` to *value*. + Set ``d[key]`` to *value*. -.. describe:: del d[key] + .. describe:: del d[key] - Remove ``d[key]`` from *d*. Raises a :exc:`KeyError` if *key* is not in the - map. + Remove ``d[key]`` from *d*. Raises a :exc:`KeyError` if *key* is not in the + map. -.. describe:: key in d + .. describe:: key in d - Return ``True`` if *d* has a key *key*, else ``False``. + Return ``True`` if *d* has a key *key*, else ``False``. -.. describe:: key not in d + .. describe:: key not in d - Equivalent to ``not key in d``. + Equivalent to ``not key in d``. -.. method:: dict.clear() + .. method:: clear() - Remove all items from the dictionary. + Remove all items from the dictionary. -.. method:: dict.copy() + .. method:: copy() - Return a shallow copy of the dictionary. + Return a shallow copy of the dictionary. -.. method:: dict.fromkeys(seq[, value]) + .. method:: fromkeys(seq[, value]) - Create a new dictionary with keys from *seq* and values set to *value*. + Create a new dictionary with keys from *seq* and values set to *value*. - :func:`fromkeys` is a class method that returns a new dictionary. *value* - defaults to ``None``. + :meth:`fromkeys` is a class method that returns a new dictionary. *value* + defaults to ``None``. -.. method:: dict.get(key[, default]) + .. method:: get(key[, default]) - Return the value for *key* if *key* is in the dictionary, else *default*. If - *default* is not given, it defaults to ``None``, so that this method never - raises a :exc:`KeyError`. + Return the value for *key* if *key* is in the dictionary, else *default*. + If *default* is not given, it defaults to ``None``, so that this method + never raises a :exc:`KeyError`. -.. method:: dict.items() + .. method:: items() - Return a new view of the dictionary's items (``(key, value)`` pairs). See - below for documentation of view objects. + Return a new view of the dictionary's items (``(key, value)`` pairs). See + below for documentation of view objects. -.. method:: dict.keys() + .. method:: keys() - Return a new view of the dictionary's keys. See below for documentation of - view objects. + Return a new view of the dictionary's keys. See below for documentation of + view objects. -.. method:: dict.pop(key[, default]) + .. method:: pop(key[, default]) - If *key* is in the dictionary, remove it and return its value, else return - *default*. If *default* is not given and *key* is not in the dictionary, a - :exc:`KeyError` is raised. + If *key* is in the dictionary, remove it and return its value, else return + *default*. If *default* is not given and *key* is not in the dictionary, + a :exc:`KeyError` is raised. -.. method:: dict.popitem() + .. method:: popitem() - Remove and return an arbitrary ``(key, value)`` pair from the dictionary. + Remove and return an arbitrary ``(key, value)`` pair from the dictionary. - :func:`popitem` is useful to destructively iterate over a dictionary, as - often used in set algorithms. If the dictionary is empty, calling - :func:`popitem` raises a :exc:`KeyError`. + :meth:`popitem` is useful to destructively iterate over a dictionary, as + often used in set algorithms. If the dictionary is empty, calling + :meth:`popitem` raises a :exc:`KeyError`. -.. method:: dict.setdefault(key[, default]) + .. method:: setdefault(key[, default]) - If *key* is in the dictionary, return its value. If not, insert *key* with - a value of *default* and return *default*. *default* defaults to ``None``. + If *key* is in the dictionary, return its value. If not, insert *key* + with a value of *default* and return *default*. *default* defaults to + ``None``. -.. method:: dict.update([other]) + .. method:: update([other]) - Update the dictionary with the key/value pairs from *other*, overwriting - existing keys. Return ``None``. + Update the dictionary with the key/value pairs from *other*, overwriting + existing keys. Return ``None``. - :func:`update` accepts either another dictionary object or an iterable of - key/value pairs (as a tuple or other iterable of length two). If keyword - arguments are specified, the dictionary is then is updated with those - key/value pairs: ``d.update(red=1, blue=2)``. + :meth:`update` accepts either another dictionary object or an iterable of + key/value pairs (as a tuple or other iterable of length two). If keyword + arguments are specified, the dictionary is then is updated with those + key/value pairs: ``d.update(red=1, blue=2)``. -.. method:: dict.values() + .. method:: values() - Return a new view of the dictionary's values. See below for documentation of - view objects. + Return a new view of the dictionary's values. See below for documentation of + view objects. Dictionary view objects diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index 48a343cdc8e..27acc71e462 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -209,12 +209,17 @@ Available Functions resulting string to *file*, which defaults to ``sys.stderr``. You may replace this function with an alternative implementation by assigning to ``warnings.showwarning``. + *line* is a line of source code to be included in the warning + message; if *line* is not supplied, :func:`showwarning` will + try to read the line specified by *filename* and *lineno*. .. function:: formatwarning(message, category, filename, lineno[, line]) Format a warning the standard way. This returns a string which may contain - embedded newlines and ends in a newline. + embedded newlines and ends in a newline. *line* is + a line of source code to be included in the warning message; if *line* is not supplied, + :func:`formatwarning` will try to read the line specified by *filename* and *lineno*. .. function:: filterwarnings(action[, message[, category[, module[, lineno[, append]]]]]) diff --git a/Lib/site.py b/Lib/site.py index 548aa626742..0df1d049380 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -184,7 +184,7 @@ def addsitedir(sitedir, known_paths=None): def check_enableusersite(): """Check if user site directory is safe for inclusion - The functions tests for the command line flag (including environment var), + The function tests for the command line flag (including environment var), process uid/gid equal to effective uid/gid. None: Disabled for security reasons diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index f6da4fe2ba2..dbc55cdf3f9 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -9,7 +9,8 @@ class AllTest(unittest.TestCase): def check_all(self, modname): names = {} with catch_warning(): - warnings.filterwarnings("ignore", ".* module", DeprecationWarning) + warnings.filterwarnings("ignore", ".* (module|package)", + DeprecationWarning) try: exec("import %s" % modname, names) except ImportError: diff --git a/Lib/test/test_json.py b/Lib/test/test_json.py index 7b8f3de8a98..17ccdeecc45 100644 --- a/Lib/test/test_json.py +++ b/Lib/test/test_json.py @@ -11,6 +11,7 @@ import test.test_support def test_main(): test.test_support.run_unittest(json.tests.test_suite()) + test.test_support.run_doctest(json) if __name__ == "__main__": diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 62d327eecef..27a01ea471a 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -42,7 +42,8 @@ def import_module(name, deprecated=False): available.""" with catch_warning(record=False): if deprecated: - warnings.filterwarnings("ignore", ".+ module", DeprecationWarning) + warnings.filterwarnings("ignore", ".+ (module|package)", + DeprecationWarning) try: module = __import__(name, level=0) except ImportError: diff --git a/Misc/TextMate/Python-Dev.tmbundle/Commands/2 to 3 - Module Deletion.tmCommand b/Misc/TextMate/Python-Dev.tmbundle/Commands/2 to 3 - Module Deletion.tmCommand index 31b88377bae..3cfada8cd56 100644 --- a/Misc/TextMate/Python-Dev.tmbundle/Commands/2 to 3 - Module Deletion.tmCommand +++ b/Misc/TextMate/Python-Dev.tmbundle/Commands/2 to 3 - Module Deletion.tmCommand @@ -6,24 +6,50 @@ nop command #!/usr/bin/python +"""Generate code to warn about a module's removal in Python 3.0. -template = """from warnings import warnpy3k +XXX Not supported: +- Module's in a package do not have their full name generated. +- Package's __init__ module; should detect and use the package's name instead. + +""" +py_template = """from warnings import warnpy3k warnpy3k("the ${1:%s} module has been removed in Python 3.0", stacklevel=2) -del warnpy3k -$0""" +del warnpy3k$0""" + +c_template = """ +if (PyErr_WarnPy3k("the ${1:%s} module has been removed in " + "Python 3.0", 2) < 0) + return;$0""" + import imp import os file_name = os.path.split(os.environ['TM_FILEPATH'])[1] -for suffix in (tuple_[0] for tuple_ in imp.get_suffixes()): - if not file_name.endswith(suffix): + +py_suffixes = reversed(sorted((suffix[0] for suffix in imp.get_suffixes() if suffix[2] == imp.PY_SOURCE), key=len)) +c_suffixes = reversed(sorted((os.path.splitext(suffix[0])[0] + '.c' + for suffix in imp.get_suffixes() if suffix[2] == imp.C_EXTENSION), key=len)) + +pairings = ((py_suffixes, py_template), (c_suffixes, c_template)) + +def create_template(suffixes, template): + for suffix in suffixes: + if not file_name.endswith(suffix): + continue + module_name = file_name[:-len(suffix)] + return template % module_name + else: + return None + +for template in (create_template(*pair) for pair in pairings): + if not template: continue - module_name = file_name[:-len(suffix)] - print (template % module_name), + print template, break else: - print (template % "XXX"), + print 'XXX Could not generate code.' input none name diff --git a/Misc/TextMate/Python-Dev.tmbundle/info.plist b/Misc/TextMate/Python-Dev.tmbundle/info.plist index 2e0ea9a6ce0..644bc7e5dde 100644 --- a/Misc/TextMate/Python-Dev.tmbundle/info.plist +++ b/Misc/TextMate/Python-Dev.tmbundle/info.plist @@ -22,10 +22,12 @@ Python-Dev ordering + 9519C22B-6AB8-41A1-94F6-079E0B45C147 B545BB1B-A8E1-426C-B50A-426E78B96D38 6EF151E5-7149-4F82-8796-0CC40FE589FA FD25A8DC-22DC-4ED4-B222-B943C8A9117D BF336FFF-E14D-4BF1-A156-71CF768AC034 + EDBB037F-AAE3-4512-863F-D9AA82C9E51E uuid A932ECD1-D43A-4F57-B7FB-A1CEC3B65D20 diff --git a/Tools/buildbot/buildmsi.bat b/Tools/buildbot/buildmsi.bat index 5625d659317..56be05e614a 100644 --- a/Tools/buildbot/buildmsi.bat +++ b/Tools/buildbot/buildmsi.bat @@ -9,7 +9,7 @@ vcbuild /useenv PCbuild\pcbuild.sln "Release|Win32" @rem build the documentation bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp' -"%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\pydoc.hhp +"%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\python30a5.hhp @rem buold the MSI file cd PC diff --git a/Tools/msi/msisupport.c b/Tools/msi/msisupport.c index b293bfc196c..f60a356c103 100644 --- a/Tools/msi/msisupport.c +++ b/Tools/msi/msisupport.c @@ -1,8 +1,6 @@ #include "windows.h" #include "msiquery.h" -int isWinNT; - /* Print a debug message to the installer log file. * To see the debug messages, install with * msiexec /i pythonxy.msi /l*v python.log @@ -30,21 +28,14 @@ UINT __declspec(dllexport) __stdcall CheckDir(MSIHANDLE hInstall) DWORD size = PSIZE; DWORD attributes; - isWinNT = (GetVersion() < 0x80000000) ? 1 : 0; - if (isWinNT) - result = MsiGetPropertyW(hInstall, L"TARGETDIR", wpath, &size); - else - result = MsiGetPropertyA(hInstall, "TARGETDIR", path, &size); + result = MsiGetPropertyW(hInstall, L"TARGETDIR", wpath, &size); if (result != ERROR_SUCCESS) return result; wpath[size] = L'\0'; path[size] = L'\0'; - if (isWinNT) - attributes = GetFileAttributesW(wpath); - else - attributes = GetFileAttributesA(path); + attributes = GetFileAttributesW(wpath); if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) { diff --git a/Tools/msi/msisupport.mak b/Tools/msi/msisupport.mak index fb960c2817d..2905dbe629c 100644 --- a/Tools/msi/msisupport.mak +++ b/Tools/msi/msisupport.mak @@ -1,25 +1,9 @@ -!IF "$(CPU)" == "" -# VS environment - # /OPT: REF and ICF are added by VS.NET by default -# NOWIN98 saves 7k of executable size, at the expense of some -# slowdown on Win98 msisupport.dll: msisupport.obj - link.exe /OUT:msisupport.dll /INCREMENTAL:NO /NOLOGO /DLL /MACHINE:X86 /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /OPT:NOWIN98 msisupport.obj msi.lib kernel32.lib + link.exe /OUT:msisupport.dll /INCREMENTAL:NO /NOLOGO /DLL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF msisupport.obj msi.lib kernel32.lib # We request a static CRT, so that there will be no CRT dependencies # for the target system. We cannot do without a CRT, since it provides # the DLL entry point. msisupport.obj: msisupport.c cl /O2 /D WIN32 /D NDEBUG /D _WINDOWS /MT /W3 /c msisupport.c - -!ELSE -# SDK environment: assume all options are already correct - -msisupport.dll: msisupport.obj - link.exe /OUT:msisupport.dll /INCREMENTAL:NO /NOLOGO /DLL msisupport.obj msi.lib kernel32.lib - -msisupport.obj: msisupport.c - cl /O2 /D WIN32 /D NDEBUG /D _WINDOWS /MD /W3 /GS- /c msisupport.c -!ENDIF -