| #!/usr/bin/env python3 | |
| # | |
| ## @file GnuMakeUtils.py | |
| # | |
| # | |
| # Copyright (c) 2025, Intel Corporation. All rights reserved.<BR> | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| # | |
| from collections import namedtuple | |
| import glob | |
| import os | |
| import re | |
| import shutil | |
| import subprocess | |
| import sys | |
| import traceback | |
| if sys.platform == 'win32': | |
| from ctypes import windll, POINTER, byref, GetLastError, Structure, WinError | |
| from ctypes import c_void_p, c_ushort, c_int, c_long, c_ulong, c_wchar, sizeof | |
| ARCH_UNKNOWN = 'Unknown' | |
| ARCH_IA32 = 'IA32' | |
| ARCH_X64 = 'X64' | |
| ARCH_AARCH64 = 'AARCH64' | |
| ARCH_RISCV64 = 'RISCV64' | |
| ARCH_LOONGARCH64 = 'LOONGARCH64' | |
| _Process = namedtuple('Process', ['process_id', 'parent_process_id', 'exe_filename']) | |
| def _get_win32_process_architecture(pid): | |
| IMAGE_FILE_MACHINE_I386 = 0x014c | |
| IMAGE_FILE_MACHINE_AMD64 = 0x8664 | |
| IMAGE_FILE_MACHINE_ARM64 = 0xAA64 | |
| def _get_machine_type(machine_id): | |
| if machine_id == IMAGE_FILE_MACHINE_I386: | |
| return ARCH_IA32 | |
| elif machine_id == IMAGE_FILE_MACHINE_AMD64: | |
| return ARCH_X64 | |
| elif machine_id == IMAGE_FILE_MACHINE_ARM64: | |
| return ARCH_AARCH64 | |
| return ARCH_UNKNOWN | |
| PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 | |
| kernel32 = windll.kernel32 | |
| OpenProcess = kernel32.OpenProcess | |
| OpenProcess.argtypes = [c_ulong, c_int, c_ulong] | |
| OpenProcess.restype = c_void_p | |
| CloseHandle = kernel32.CloseHandle | |
| CloseHandle.argtypes = [c_void_p] | |
| CloseHandle.restype = c_int | |
| IsWow64Process2 = None | |
| IMAGE_FILE_MACHINE_UNKNOWN = 0 | |
| try: | |
| #IsWow64Process2() is only available on Win10 TH2 or later | |
| IsWow64Process2 = kernel32.IsWow64Process2 | |
| except AttributeError: | |
| IsWow64Process2 = None | |
| if IsWow64Process2 is not None: | |
| IsWow64Process2.argtypes = [c_void_p, POINTER(c_ushort), POINTER(c_ushort)] | |
| IsWow64Process2.restype = c_int | |
| ProcessMachine = c_ushort(1) | |
| NativeMachine = c_ushort(1) | |
| hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid) | |
| if hProcess == c_void_p(0): | |
| raise WinError(GetLastError()) | |
| if IsWow64Process2(hProcess, byref(ProcessMachine), byref(NativeMachine)) != 0: | |
| CloseHandle(hProcess) | |
| if ProcessMachine.value == IMAGE_FILE_MACHINE_UNKNOWN: | |
| return _get_machine_type(NativeMachine.value) | |
| else: | |
| return _get_machine_type(ProcessMachine.value) | |
| else: | |
| CloseHandle(hProcess) | |
| raise WinError(GetLastError()) | |
| else: | |
| #Graceful fallback for older OSes | |
| PROCESSOR_ARCHITECTURE_INTEL = 0 | |
| PROCESSOR_ARCHITECTURE_AMD64 = 9 | |
| class _SYSTEM_INFO(Structure): | |
| _fields_ = [('wProcessorArchitecture', c_ushort), | |
| ('wReserved', c_ushort), | |
| ('dwPageSize', c_ulong), | |
| ('lpMinimumApplicationAddress', c_void_p), | |
| ('lpMaximumApplicationAddress', c_void_p), | |
| ('dwActiveProcessorMask', c_void_p), | |
| ('dwNumberOfProcessors', c_ulong), | |
| ('dwProcessorType', c_ulong), | |
| ('dwAllocationGranularity', c_ulong), | |
| ('wProcessorLevel', c_ushort), | |
| ('wProcessorRevision', c_ushort)] | |
| GetNativeSystemInfo = kernel32.GetNativeSystemInfo | |
| GetNativeSystemInfo.argtypes = [POINTER(_SYSTEM_INFO)] | |
| systemInfo = _SYSTEM_INFO() | |
| GetNativeSystemInfo(byref(systemInfo)) | |
| if systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64: | |
| hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid) | |
| if hProcess == c_void_p(0): | |
| raise WinError(GetLastError()) | |
| IsWow64Process = kernel32.IsWow64Process | |
| IsWow64Process.argtypes = [c_void_p, POINTER(c_int)] | |
| IsWow64Process.restype = c_int | |
| is_wow64 = c_int(0) | |
| if IsWow64Process(hProcess, byref(is_wow64)) != 0: | |
| CloseHandle(hProcess) | |
| if is_wow64.value != 0: | |
| return ARCH_IA32 | |
| else: | |
| return ARCH_X64 | |
| else: | |
| CloseHandle(hProcess) | |
| raise WinError(GetLastError()) | |
| elif systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL: | |
| return ARCH_IA32 | |
| return ARCH_UNKNOWN | |
| def _get_win32_process_list(): | |
| class _PROCESSENTRY32W(Structure): | |
| _fields_ = [('dwSize', c_ulong), | |
| ('cntUsage', c_ulong), | |
| ('th32ProcessID', c_ulong), | |
| ('th32DefaultHeapID', c_void_p), | |
| ('th32ModuleID', c_ulong), | |
| ('cntThreads', c_ulong), | |
| ('th32ParentProcessID', c_ulong), | |
| ('pcPriClassBase', c_long), | |
| ('dwFlags', c_ulong), | |
| ('szExeFile', (c_wchar * 260))] | |
| INVALID_HANDLE_VALUE = c_void_p(-1) | |
| TH32CS_SNAPPROCESS = 2 | |
| ERROR_NO_MORE_FILES = 18 | |
| kernel32 = windll.kernel32 | |
| CreateToolhelp32Snapshot = kernel32.CreateToolhelp32Snapshot | |
| CreateToolhelp32Snapshot.argtypes = [c_ulong, c_ulong] | |
| CreateToolhelp32Snapshot.restype = c_void_p | |
| Process32First = kernel32.Process32FirstW | |
| Process32First.argtypes = [c_void_p, POINTER(_PROCESSENTRY32W)] | |
| Process32First.restype = c_int | |
| Process32Next = kernel32.Process32NextW | |
| Process32Next.argtypes = [c_void_p, POINTER(_PROCESSENTRY32W)] | |
| Process32Next.restype = c_int | |
| CloseHandle = kernel32.CloseHandle | |
| CloseHandle.argtypes = [c_void_p] | |
| CloseHandle.restype = c_int | |
| hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) | |
| if hSnapshot == INVALID_HANDLE_VALUE.value: | |
| raise WinError(GetLastError()) | |
| process_list = [] | |
| processEntry = _PROCESSENTRY32W() | |
| processEntry.dwSize = sizeof(processEntry) | |
| more_processes = True | |
| if Process32First(hSnapshot, byref(processEntry)) == 0: | |
| raise WinError(GetLastError()) | |
| while more_processes: | |
| process_list.append(_Process(processEntry.th32ProcessID, processEntry.th32ParentProcessID, processEntry.szExeFile)) | |
| if Process32Next(hSnapshot, byref(processEntry)) == 0: | |
| status = GetLastError() | |
| if status == ERROR_NO_MORE_FILES: | |
| more_processes = False | |
| else: | |
| raise WinError(status) | |
| CloseHandle(hSnapshot) | |
| return process_list | |
| def _get_win32_parent_processes(): | |
| kernel32 = windll.kernel32 | |
| GetCurrentProcessId = kernel32.GetCurrentProcessId | |
| GetCurrentProcessId.argtypes = [] | |
| GetCurrentProcessId.restype = c_ulong | |
| process_list = _get_win32_process_list() | |
| pid = GetCurrentProcessId() | |
| parent_processes = [] | |
| found_parent = True | |
| while found_parent: | |
| found_parent = False | |
| for process in process_list: | |
| if process.process_id == pid: | |
| found_parent = True | |
| parent_processes.append(process) | |
| pid = process.parent_process_id | |
| break | |
| return parent_processes | |
| def _get_mingw_target_architecture(): | |
| parent_processes = _get_win32_parent_processes() | |
| for process in parent_processes: | |
| if 'make' in process.exe_filename.lower(): | |
| return _get_win32_process_architecture(process.process_id) | |
| return ARCH_UNKNOWN | |
| def get_host_arch(): | |
| if sys.platform == 'win32': | |
| host_arch = _get_mingw_target_architecture() | |
| else: | |
| result = subprocess.run('uname -m', universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, check=True) | |
| uname_m = result.stdout.strip() | |
| ia32_regex = re.compile(r".*i[8]?[0-9]86.*") | |
| ia32_match = ia32_regex.match(uname_m) | |
| if 'x86_64' in uname_m or 'amd64' in uname_m: | |
| host_arch = ARCH_X64 | |
| elif ia32_match: | |
| host_arch = ARCH_IA32 | |
| elif 'aarch64' in uname_m or 'arm64' in uname_m: | |
| host_arch = ARCH_AARCH64 | |
| elif 'riscv64' in uname_m: | |
| host_arch = ARCH_RISCV64 | |
| elif 'loongarch64' in uname_m: | |
| host_arch = ARCH_LOONGARCH64 | |
| print(host_arch) | |
| return 0 | |
| def main(): | |
| if sys.argv[1] == 'get_host_arch': | |
| return get_host_arch() | |
| elif sys.argv[1] == 'cp': | |
| shutil.copy(os.path.normpath(sys.argv[2]), os.path.normpath(sys.argv[3])) | |
| elif sys.argv[1] == 'mv': | |
| shutil.move(os.path.normpath(sys.argv[2]), os.path.normpath(sys.argv[3])) | |
| elif sys.argv[1] == 'rm': | |
| paths = [os.path.normpath(x) for x in sys.argv[2:]] | |
| files = [] | |
| for path in paths: | |
| if '*' in path: | |
| files.extend(glob.glob(path)) | |
| else: | |
| files.append(path) | |
| for file in files: | |
| if os.path.exists(file): | |
| if os.path.isfile(file): | |
| os.remove(file) | |
| else: | |
| sys.stderr.writelines(['{} is not a file.'.format(file)]) | |
| else: | |
| sys.stderr.writelines(['File {} does not exist.'.format(file)]) | |
| elif sys.argv[1] == 'md': | |
| path = os.path.normpath(sys.argv[2]) | |
| if not os.path.exists(path): | |
| os.makedirs(path) | |
| else: | |
| if os.path.isdir(path): | |
| sys.stderr.writelines(['Directory {} already exists.'.format(path)]) | |
| else: | |
| sys.stderr.writelines(['{} is a file.'.format(path)]) | |
| return 1 | |
| elif sys.argv[1] == 'rd': | |
| paths = [os.path.normpath(x) for x in sys.argv[2:]] | |
| for path in paths: | |
| if os.path.exists(path): | |
| if os.path.isdir(path): | |
| shutil.rmtree(path) | |
| else: | |
| sys.stderr.writelines(['{} is not a directory.'.format(path)]) | |
| else: | |
| sys.stderr.writelines(['Directory {} does not exist.'.format(path)]) | |
| elif sys.argv[1] == 'rm_pyc_files': | |
| path = os.path.normpath(sys.argv[2]) | |
| files = glob.glob(os.path.join(path, '*.pyc')) | |
| for file in files: | |
| if os.path.exists(file): | |
| if os.path.isfile(file): | |
| os.remove(file) | |
| else: | |
| sys.stderr.writelines(['{} is not a file.'.format(file)]) | |
| else: | |
| sys.stderr.writelines(['File {} does not exist.'.format(file)]) | |
| py_cache = os.path.join(path, '__pycache__') | |
| if os.path.isdir(py_cache): | |
| shutil.rmtree(py_cache) | |
| else: | |
| sys.stderr.writelines(['Unsupported command.']) | |
| return 1 | |
| return 0 | |
| if __name__ == '__main__': | |
| try: | |
| sys.exit(main()) | |
| except Exception as e: | |
| traceback.print_exc() | |
| sys.exit(1) |