blob: 6f686fd7aa2523384f855e0c4c4662f55a29182d [file] [log] [blame]
#!/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)