summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-12-18 05:23:04 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-12-18 05:23:04 +0000
commit408f23394780da9b1e5e14380fe21bcac19a93a9 (patch)
tree1b0ba9ecfc2d495d6c293110c6331a77304e35e1 /scripts
parent47ff745210c71ba79033fb69a7f832aa18b87977 (diff)
downloadgtest-408f23394780da9b1e5e14380fe21bcac19a93a9.tar.gz
gtest-408f23394780da9b1e5e14380fe21bcac19a93a9.tar.bz2
gtest-408f23394780da9b1e5e14380fe21bcac19a93a9.tar.xz
Supports building gtest as a DLL (by Vlad Losev).
git-svn-id: http://googletest.googlecode.com/svn/trunk@354 861a406c-534a-0410-8894-cb66d6ee9925
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/generate_gtest_def.py169
1 files changed, 169 insertions, 0 deletions
diff --git a/scripts/generate_gtest_def.py b/scripts/generate_gtest_def.py
new file mode 100755
index 0000000..9de7038
--- /dev/null
+++ b/scripts/generate_gtest_def.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Generates the gtest.def file to build Google Test as a DLL on Windows.
+
+SYNOPSIS
+ Put diagnostic messages from building gtest_dll_test_.exe into
+ BUILD_RESULTS_FILE and invoke
+
+ generate_gtest_def.py <BUILD_RESULTS_FILE
+
+ Reads output of VC++ linker and re-generates the src/gtest.def file
+ required for building gtest as a DLL.
+
+ Use this script if you modify Google Test's source code and Visual
+ Studio linker starts complaining about unresolved external symbols.
+ You may have to repeate the build/re-generate cycle several times
+ because VC++ limits the number of unresolved external symbols it can
+ report at a time.
+
+EXAMPLES
+ scons\scons.py | scripts\generate_gtest_def.py
+
+This tool is experimental. Please report any problems to
+googletestframework@googlegroups.com. You can read
+http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for more
+information.
+"""
+
+__author__ = 'vladl@google.com (Vlad Losev)'
+
+import os
+import re
+import sets
+import sys
+
+# We assume that this file is in the scripts/ directory in the Google
+# Test root directory.
+GTEST_DEF_PATH = os.path.join(os.path.dirname(__file__), '../src/gtest.def')
+
+# Locates the header of the EXPORTS section.
+EXPORTS_SECTION_REGEX = re.compile(r'^EXPORTS\s*$', re.IGNORECASE)
+
+# Determines if a line looks like an export definition in the EXPORTS
+# section of a module definition file.
+EXPORT_REGEX = re.compile(r'^\s+(\S+)')
+
+# Determines if a given line contains an error message about unresolved
+# linker symbol.
+IS_UNRESOLVED_SYMBOL_REGEX = re.compile(r'\bunresolved external symbol\b')
+
+# Fetches the symbol name from a line that contains an unresolved linker
+# symbol message.
+UNRESOLVED_SYMBOL_REGEX = re.compile(r'^.*?"[^"]+" \((\S+)\)')
+
+
+def ReadDefExports(stream):
+ """Reads contents of a def file and returns a list of exported symbols."""
+
+ is_export = False
+ exports = sets.Set()
+ for line in stream:
+ if EXPORTS_SECTION_REGEX.match(line):
+ is_export = True
+ elif EXPORT_REGEX.match(line):
+ if is_export:
+ exports.add(EXPORT_REGEX.match(line).group(1))
+ else:
+ is_export = False
+
+ return exports
+
+
+def ReadUnresolvedExternals(stream):
+ """Reads linker output and returns list of unresolved linker symbols."""
+
+ unresolved = sets.Set()
+
+ for line in stream:
+ if IS_UNRESOLVED_SYMBOL_REGEX.search(line):
+ unresolved.add(UNRESOLVED_SYMBOL_REGEX.match(line).group(1))
+
+ return unresolved
+
+
+def AdjustExports(exports, unresolved):
+ """Adjusts exports list based on the list of unresolved symbols."""
+
+ if unresolved & exports:
+ # There are symbols that are listed as exported but are also reported
+ # unresolved. This is most likely because they have been removed from
+ # Google Test but their mentions in gtest.def constitute references. We
+ # need to remove such symbols from the EXPORTS section. Also, their
+ # presence means that the Google Test DLL has failed to link and
+ # consequently linking of the test .exe was not attempted, meaning that
+ # at this time, there will be no unresolved externals that need to be
+ # added to the exports list.
+ exports -= unresolved
+ else:
+ # Finding unresolved exports means that the Google Test DLL had link
+ # errors and the build script did not build gtest_dll_test_.exe. The user
+ # has to build the test once again and run this script on the diagnostic
+ # output of the build.
+ exports |= unresolved
+
+ return exports
+
+
+def WriteGtestDefFile(stream, exports):
+ """Writes contents of gtest.def given a list of exported symbols."""
+
+ stream.write('; This file is auto-generated. DO NOT EDIT DIRECTLY.\n'
+ '; For more information, see scripts/generate_gtest_def.py.\n'
+ '\nLIBRARY\n'
+ '\nEXPORTS\n')
+ for symbol in sorted(exports):
+ stream.write(' %s\n' % symbol)
+
+
+def main():
+ unresolved = ReadUnresolvedExternals(sys.stdin)
+ if unresolved:
+ try:
+ gtest_def = open(GTEST_DEF_PATH, 'r')
+ exports = ReadDefExports(gtest_def)
+ gtest_def.close()
+ except IOError:
+ exports = sets.Set()
+
+ exports = AdjustExports(exports, unresolved)
+ WriteGtestDefFile(open(GTEST_DEF_PATH, 'w'), exports)
+ sys.stderr.write('Updated test/gtest.def. Please clean the .dll file\n'
+ 'produced by your Google Test DLL build, run the build\n'
+ 'again and pass its diagnostic output to this script\n'
+ 'unless the build succeeds.\n')
+ else:
+ sys.stderr.write('The build diagnostic output indicates no unresolved\n'
+ 'externals. test/gtest.def is likely up to date and\n'
+ 'has not been updated.\n')
+
+if __name__ == '__main__':
+ main()