#!/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) |