1#!/usr/bin/env python3 2# 3# Copyright 2020 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from distutils import log 18from distutils.errors import DistutilsModuleError 19import os 20from setuptools import find_packages 21from setuptools import setup 22from setuptools.command.install import install 23import stat 24import subprocess 25import sys 26 27install_requires = [ 28 'grpcio', 29 'psutil', 30] 31 32host_executables = [ 33 'root-canal', 34 'bluetooth_stack_with_facade', # c++ 35 'bluetooth_with_facades', # rust 36] 37 38 39# Need to verify acts is importable in a new Python context 40def is_acts_importable(): 41 cmd = [sys.executable, '-c', 'import acts'] 42 completed_process = subprocess.run(cmd, cwd=os.getcwd()) 43 return completed_process.returncode == 0 44 45 46def setup_acts_for_cmd_or_die(cmd_str): 47 acts_framework_dir = os.path.abspath('acts_framework') 48 acts_setup_bin = os.path.join(acts_framework_dir, 'setup.py') 49 cmd = [sys.executable, acts_setup_bin, cmd_str] 50 subprocess.run(cmd, cwd=acts_framework_dir, check=True) 51 52 53def set_permissions_for_host_executables(outputs): 54 for file in outputs: 55 if os.path.basename(file) in host_executables: 56 current_mode = os.stat(file).st_mode 57 new_mode = current_mode | stat.S_IEXEC 58 os.chmod(file, new_mode) 59 log.log(log.INFO, "Changed file mode of %s from %s to %s" % (file, oct(current_mode), oct(new_mode))) 60 61 62class InstallLocalPackagesForInstallation(install): 63 64 user_options = install.user_options + [ 65 ('reuse-acts', None, "Skip ACTS installation if already installed"), 66 ] 67 boolean_options = install.boolean_options + ['reuse-acts'] 68 69 def initialize_options(self): 70 install.initialize_options(self) 71 self.reuse_acts = False 72 73 def run(self): 74 if self.reuse_acts and is_acts_importable(): 75 self.announce('Reusing existing ACTS installation', log.WARN) 76 else: 77 self.announce('Installing ACTS library', log.WARN) 78 setup_acts_for_cmd_or_die("install") 79 self.announce('ACTS installed.', log.WARN) 80 if not is_acts_importable(): 81 raise DistutilsModuleError("Cannot import acts after installation") 82 install.run(self) 83 set_permissions_for_host_executables(self.get_outputs()) 84 85 86def main(): 87 # Relative path from calling directory to this file 88 our_dir = os.path.dirname(__file__) 89 # Must cd into this dir for package resolution to work 90 # This won't affect the calling shell 91 os.chdir(our_dir) 92 setup( 93 name='bluetooth_cert_tests', 94 version='1.0', 95 author='Android Open Source Project', 96 license='Apache2.0', 97 description="""Bluetooth Cert Tests Package""", 98 # Include root package so that bluetooth_packets_python3.so can be 99 # included as well 100 packages=[''] + 101 find_packages(exclude=['acts_framework', 'acts_framework.*', 'llvm_binutils', 'llvm_binutils.*']), 102 install_requires=install_requires, 103 package_data={ 104 '': host_executables + ['*.so', 'lib64/*.so', 'target/*', 'llvm_binutils/bin/*', 'llvm_binutils/lib64/*'], 105 'cert': ['all_test_cases'], 106 }, 107 cmdclass={ 108 'install': InstallLocalPackagesForInstallation, 109 }) 110 111 112if __name__ == '__main__': 113 main() 114