#!/usr/bin/env python3 # # Copyright 2020 - 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. from distutils import log from distutils.errors import DistutilsModuleError import os from setuptools import find_packages from setuptools import setup from setuptools.command.install import install import stat import subprocess import sys install_requires = [ 'grpcio', 'psutil', ] host_executables = [ 'root-canal', 'bluetooth_stack_with_facade', # c++ 'bluetooth_with_facades', # rust ] # Need to verify acts is importable in a new Python context def is_acts_importable(): cmd = [sys.executable, '-c', 'import acts'] completed_process = subprocess.run(cmd, cwd=os.getcwd()) return completed_process.returncode == 0 def setup_acts_for_cmd_or_die(cmd_str): acts_framework_dir = os.path.abspath('acts_framework') acts_setup_bin = os.path.join(acts_framework_dir, 'setup.py') cmd = [sys.executable, acts_setup_bin, cmd_str] subprocess.run(cmd, cwd=acts_framework_dir, check=True) def set_permissions_for_host_executables(outputs): for file in outputs: if os.path.basename(file) in host_executables: current_mode = os.stat(file).st_mode new_mode = current_mode | stat.S_IEXEC os.chmod(file, new_mode) log.log(log.INFO, "Changed file mode of %s from %s to %s" % (file, oct(current_mode), oct(new_mode))) class InstallLocalPackagesForInstallation(install): user_options = install.user_options + [ ('reuse-acts', None, "Skip ACTS installation if already installed"), ] boolean_options = install.boolean_options + ['reuse-acts'] def initialize_options(self): install.initialize_options(self) self.reuse_acts = False def run(self): if self.reuse_acts and is_acts_importable(): self.announce('Reusing existing ACTS installation', log.WARN) else: self.announce('Installing ACTS library', log.WARN) setup_acts_for_cmd_or_die("install") self.announce('ACTS installed.', log.WARN) if not is_acts_importable(): raise DistutilsModuleError("Cannot import acts after installation") install.run(self) set_permissions_for_host_executables(self.get_outputs()) def main(): # Relative path from calling directory to this file our_dir = os.path.dirname(__file__) # Must cd into this dir for package resolution to work # This won't affect the calling shell os.chdir(our_dir) setup( name='bluetooth_cert_tests', version='1.0', author='Android Open Source Project', license='Apache2.0', description="""Bluetooth Cert Tests Package""", # Include root package so that bluetooth_packets_python3.so can be # included as well packages=[''] + find_packages(exclude=['acts_framework', 'acts_framework.*', 'llvm_binutils', 'llvm_binutils.*']), install_requires=install_requires, package_data={ '': host_executables + ['*.so', 'lib64/*.so', 'target/*', 'llvm_binutils/bin/*', 'llvm_binutils/lib64/*'], 'cert': ['all_test_cases'], }, cmdclass={ 'install': InstallLocalPackagesForInstallation, }) if __name__ == '__main__': main()