| #!/usr/bin/env python |
| # |
| # Copyright 2016 - The Android Open Source Project |
| # |
| # 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 argparse |
| import math |
| |
| |
| class Module(object): |
| """class used to represent a ltp module |
| |
| Attribute: |
| _lines: list of string, lines of module text |
| _header: list of string, first line of module splited by := |
| _type: string, type of module |
| _path: string, path of module |
| _output_dir: string, output directory of module |
| """ |
| _lines = None |
| _header = None |
| _type = None |
| _path = None |
| _output_dir = None |
| |
| def __init__(self, output_dir): |
| self._output_dir = output_dir |
| |
| def parse(self, module_text): |
| """parse a module text |
| |
| Args: |
| module_text: string, one block of ltp module build rule. |
| output_dir: string, ltp compile output directory |
| |
| Return: |
| None if the input text is not a ltp module |
| Self if parsed succesfully |
| """ |
| self._lines = module_text.splitlines() |
| if len(self._lines) < 2: |
| self._type = None |
| return None |
| self._header = self._lines[0].split(' := ') |
| if len(self._header) < 2: |
| self._type = None |
| return None |
| self._type = self._header[0] |
| self._path = self._header[1] |
| return self |
| |
| def IsBuildSuccess(self, counts): |
| """Check whether a given module specified in Android.mk file |
| is succesfully built |
| |
| Returns: |
| True if success |
| """ |
| if self._type is None: |
| return False |
| |
| counts[self._type] = counts.get(self._type, 0) + 1 |
| |
| success = {"module_testname": self.IsBuildSuccessModuleTestname, |
| "module_libname": self.IsBuildSuccessModuleLibname, |
| "module_prebuilt": self.IsBuildSuccessModulePrebuilt, |
| }[self._type]() |
| |
| if not success: |
| print " Module build failed: " + os.path.basename(self._path) |
| return success |
| |
| def IsBuildSuccessModuleTestname(self): |
| """Check whether a given ltp test module in Android.mk file |
| is succesfully built |
| |
| Args: |
| module_path: string, the path of module on the first |
| line of the block |
| |
| Returns: |
| True if success |
| """ |
| |
| return os.path.isfile(self._output_dir + \ |
| "testcases/bin/" + \ |
| os.path.basename(self._path)) |
| |
| def IsBuildSuccessModuleLibname(self): |
| """Check whether a given ltp lib module in Android.mk file |
| is succesfully built |
| |
| Args: |
| module_path: the path of module on the first line of |
| the block |
| |
| Returns: |
| True if success |
| """ |
| # TODO(yuexima) check lib build |
| print "Checking module_lib is not supported now, " + \ |
| "assuming build success: " + self._path |
| return True |
| |
| def IsBuildSuccessModulePrebuilt(self): |
| """Check whether a given prebuilt module in Android.mk file |
| is succesfully built |
| |
| Args: |
| module_path: string, the path of module on the first |
| line of the block |
| |
| Returns: |
| True if success |
| """ |
| return os.path.isfile(self._output_dir + self._path) |
| |
| |
| class LtpModuleChecker(object): |
| """LTP module result check class. |
| Checks for success build of each module in LTP's Android.mk file |
| and rewrite it with only successfully built modules. |
| """ |
| _output_dir = "" |
| _file_path_android_ltp_mk = "" |
| _module_counts = {} |
| |
| def __init__(self, android_build_top, ltp_dir, target_product): |
| self._output_dir = android_build_top + '/out/target/product/' + \ |
| target_product + '/data/nativetest/ltp/' |
| self._file_path_android_ltp_mk = ltp_dir + '/Android.ltp.mk' |
| |
| def Read(self, file_path): |
| """Read a file and return its entire content |
| |
| Args: |
| file_path: string, file path |
| |
| Returns: |
| entire file content in string format |
| """ |
| with open(file_path, 'r') as file: |
| return file.read() |
| |
| def LoadModules(self): |
| """Read the LTP Android.mk file and seperate modules into |
| a list of string |
| """ |
| return self.Read(self._file_path_android_ltp_mk).split("\n\n") |
| |
| def CheckModules(self): |
| """Start the LTP module build result checking and counting.""" |
| modules = [Module(self._output_dir).parse(module) |
| for module in self.LoadModules()] |
| modules_succeed = \ |
| [module for module in modules |
| if module is not None and |
| module.IsBuildSuccess(self._module_counts) |
| ] |
| |
| print "module type counts:" |
| print self._module_counts |
| |
| print str(len(modules_succeed)) + \ |
| " of " + str(sum([self._module_counts[i] |
| for i in self._module_counts])) + \ |
| " modules were succesfully built." |
| print "--Check complete." |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser( |
| description='Generate Android.mk from parsed LTP make output') |
| parser.add_argument( |
| '--android_build_top', |
| dest='android_build_top', |
| required=True, |
| help='android build top directory') |
| parser.add_argument( |
| '--ltp_dir', |
| dest='ltp_dir', |
| required=True, |
| help='directory for the forked ltp project') |
| parser.add_argument( |
| '--target_product', |
| dest='target_product', |
| required=True, |
| help='target product name, \ |
| such as "bullhead", "angler", etc.') |
| args = parser.parse_args() |
| |
| checker = LtpModuleChecker(args.android_build_top, args.ltp_dir, |
| args.target_product) |
| checker.CheckModules() |
| |
| |
| if __name__ == '__main__': |
| main() |