diff options
author | Yun Peng <pcloudy@google.com> | 2017-08-25 09:59:14 +0200 |
---|---|---|
committer | Yun Peng <pcloudy@google.com> | 2017-08-28 09:37:47 +0200 |
commit | 66437a0173488ca4e77aab8c41d5454871c8c6a2 (patch) | |
tree | 3527d0aff2c40c5be751aa972d880b27e6eb6aa2 /third_party/def_parser/def_parser_test.py | |
parent | 9e3a3e2f6a16288febc74a4a3c9086c995f6aa5a (diff) |
Windows: Implementing C++ DEF parser
C++ DEF parser can generating a DEF file from a object file, which can
be used to export symbols during linking DLL on Windows.
This parser is based on an implementation in CMake
See https://github.com/Kitware/CMake/blob/master/Source/bindexplib.cxx
A few changes has been made to make it work better.
Usage: output_deffile dllname [objfile ...] [input_deffile ...] [@paramfile ...]
output_deffile: the output DEF file
dllname: the DLL name this DEF file is used for, if dllname is not empty
string (eg. ""), def_parser writes an 'LIBRARY <dllname>' entry
into DEF file.
objfile: a object file, def_parser parses this file to find symbols,
then merges them into final result.
Can apppear multiple times.
input_deffile: an existing def file, def_parser merges all symbols in this file.
Can appear multiple times.
@paramfile: a parameter file that can contain objfile and input_deffile
Can appear multiple time.
Change-Id: I0ee65fa3119ecae2ea195b707af5690e4bc6a6c2
Diffstat (limited to 'third_party/def_parser/def_parser_test.py')
-rw-r--r-- | third_party/def_parser/def_parser_test.py | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/third_party/def_parser/def_parser_test.py b/third_party/def_parser/def_parser_test.py new file mode 100644 index 0000000000..a413c3ad5a --- /dev/null +++ b/third_party/def_parser/def_parser_test.py @@ -0,0 +1,108 @@ +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest +from src.test.py.bazel import test_base + +class DEFParserTest(test_base.TestBase): + + def createAndBuildProjectFiles(self): + self.ScratchFile('WORKSPACE') + self.ScratchFile('BUILD', ['cc_library(name="hello", srcs=["x.cc"])']) + self.ScratchFile('x.cc', [ + '#include <stdio.h>', + 'int hello_data;', + 'void hello_world() {', + ' printf("hello world\\n");', + '}', + ]) + exit_code, _, stderr = self.RunBazel(['build', '//:hello']) + self.AssertExitCode(exit_code, 0, stderr) + + def testParseDefFileFromObjectFile(self): + # Skip this test on non-Windows platforms + if not self.IsWindows(): + return + self.createAndBuildProjectFiles() + + exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin']) + self.AssertExitCode(exit_code, 0, stderr) + bazel_bin = stdout[0] + + objfile = os.path.join(bazel_bin, '_objs', 'hello', 'x.o') + self.assertTrue(os.path.isfile(objfile)) + output_def = self.Path('x.def'); + self.RunProgram([self.Rlocation('io_bazel/third_party/def_parser/def_parser.exe'), output_def, 'my_x.dll', objfile]) + self.assertTrue(os.path.isfile(output_def)) + + with open(output_def, 'r') as def_file: + def_content = def_file.read() + self.assertIn('LIBRARY my_x.dll', def_content) + self.assertIn('hello_data', def_content) + self.assertIn('hello_world', def_content) + + def testParseDefFileFromObjectFileWithParamFile(self): + # Skip this test on non-Windows platforms + if not self.IsWindows(): + return + self.createAndBuildProjectFiles() + + exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin']) + self.AssertExitCode(exit_code, 0, stderr) + bazel_bin = stdout[0] + + objfile = os.path.join(bazel_bin, '_objs', 'hello', 'x.o') + self.assertTrue(os.path.isfile(objfile)) + objfilelist = self.ScratchFile('objfilelist', [objfile]) + + output_def = self.Path('x.def'); + self.RunProgram([self.Rlocation('io_bazel/third_party/def_parser/def_parser.exe'), output_def, 'my_x.dll', '@' + objfilelist]) + self.assertTrue(os.path.isfile(output_def)) + + with open(output_def, 'r') as def_file: + def_content = def_file.read() + self.assertIn('LIBRARY my_x.dll', def_content) + self.assertIn('hello_data', def_content) + self.assertIn('hello_world', def_content) + + def testParseDefFileFromAnotherDefFile(self): + # Skip this test on non-Windows platforms + if not self.IsWindows(): + return + + self.createAndBuildProjectFiles() + + exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin']) + self.AssertExitCode(exit_code, 0, stderr) + bazel_bin = stdout[0] + + objfile = os.path.join(bazel_bin, '_objs', 'hello', 'x.o') + self.assertTrue(os.path.isfile(objfile)) + output_def = self.Path('x.def'); + self.RunProgram([self.Rlocation('io_bazel/third_party/def_parser/def_parser.exe'), output_def, 'my_x.dll', objfile]) + self.assertTrue(os.path.isfile(output_def)) + + new_output_def = self.Path('new_x.def'); + self.RunProgram([self.Rlocation('io_bazel/third_party/def_parser/def_parser.exe'), new_output_def, 'my_x.dll', output_def]) + self.assertTrue(os.path.isfile(new_output_def)) + + with open(new_output_def, 'r') as def_file: + def_content = def_file.read() + self.assertIn('LIBRARY my_x.dll', def_content) + self.assertIn('hello_data', def_content) + self.assertIn('hello_world', def_content) + +if __name__ == '__main__': + unittest.main() |