Files
FEX-Emu--FEX/Scripts/StructPackVerifier.py
crueter 9e8463d6d7 [cmake] refactor: compiler and architecture handling
- Do compiler/architecture checks EARLY, don't waste time doing random
  configuration stuff if the user can't even compile in the first place
- MSVC is unsupported, I assume? So add a check to disallow. There's
  literally no MSVC or MSC_VER checks anywhere, so...
- Rather than using the MSVC architecture definitions, use our own
  `ARCHITECTURE_arm64` et al. Hijacking existing "standard" definitions
  is a very bad idea. Also makes it more readable in CMake
- Change the x86 host check to `x86|amd64`. Some systems still refer to
  themselves as x86 despite being 64-bit for... reasons, and I saw one a
  very long time ago that referred to it as amd64. This should
  basically never come up, nor is it really relevant given that FEX is
  for arm64... but it kinda annoyed me so whatever.

TODOs:
- Should we check `CMAKE_SIZEOF_VOID_P (equal) 64`? I don't think anyone
  is even trying to compile this thing on armv7 or older, but might as
  well? maybe?
- What's the status of *BSD, Solaris, macOS? Technically macOS does
  support Wine, not sure about the others.

Signed-off-by: crueter <crueter@eden-emu.dev>
2025-12-29 14:05:09 -05:00

779 lines
26 KiB
Python
Executable File

#!/usr/bin/python3
import clang.cindex
from clang.cindex import CursorKind
from clang.cindex import TypeKind
from clang.cindex import TranslationUnit
import sys
from dataclasses import dataclass
import subprocess
import logging
logger = logging.getLogger()
logger.setLevel(logging.WARNING)
# These defines are temporarily defined since python3-clang doesn't yet support these.
# Once this tool gets switched over to C++ then this won't be an issue.
# Type definitions redeclared from `clang/include/clang-c/Index.h`
# Expression that references a C++20 concept.
CursorKind.CONCEPTSPECIALIZATIONEXPR = CursorKind(153),
# Expression that references a C++20 concept.
CursorKind.REQUIRESEXPR = CursorKind(154),
# C++2a std::bit_cast expression.
CursorKind.BUILTINBITCASTEXPR = CursorKind(280)
try:
# a concept declaration.
CursorKind.CONCEPTDECL = CursorKind(604),
except:
pass
@dataclass
class TypeDefinition:
TYPE_UNKNOWN = 0
TYPE_STRUCT = 1
TYPE_UNION = 2
TYPE_FIELD = 3
TYPE_VARDECL = 4
name: str
type: int
def __init__(self, Name, Type):
self.name = Name
self.type = Type
@property
def Name(self):
return self.name
@property
def Type(self):
return self.type
@dataclass
class AliasType:
ALIAS_X86_32 = 0
ALIAS_X86_64 = 1
ALIAS_AARCH64 = 2
ALIAS_WIN32 = 3
ALIAS_WIN64 = 4
Name: str
AliasType: int
def __init__(self, Name, Type):
self.Name = Name
self.AliasType = Type
@dataclass
class StructDefinition(TypeDefinition):
Size: int
Aliases: list
Members: list
ExpectFEXMatch: bool
def __init__(self, Name, Size):
super(StructDefinition, self).__init__(Name, TypeDefinition.TYPE_STRUCT)
self.Size = Size
self.Aliases = []
self.Members = []
self.ExpectFEXMatch = False
@dataclass
class UnionDefinition(TypeDefinition):
Size: int
Aliases: list
Members: list
ExpectFEXMatch: bool
def __init__(self, Name, Size):
super(UnionDefinition, self).__init__(Name, TypeDefinition.TYPE_UNION)
self.Size = Size
self.Aliases = []
self.Members = []
self.ExpectFEXMatch = False
@dataclass
class FieldDefinition(TypeDefinition):
Size: int
OffsetOf: int
Alignment: int
def __init__(self, Name, Size, OffsetOf, Alignment):
super(FieldDefinition, self).__init__(Name, TypeDefinition.TYPE_FIELD)
self.Size = Size
self.OffsetOf = OffsetOf
self.Alignment = Alignment
@dataclass
class VarDeclDefinition(TypeDefinition):
Size: int
Aliases: list
ExpectFEXMatch: bool
Value: str
def __init__(self, Name, Size):
super(VarDeclDefinition, self).__init__(Name, TypeDefinition.TYPE_VARDECL)
self.Size = Size
self.Aliases = []
self.ExpectFEXMatch = False
@dataclass
class ArchDB:
Parsed: bool
ArchName: str
NamespaceScope: list
CurrentNamespace: str
TU: TranslationUnit
Structs: dict
Unions: dict
VarDecls: dict
FieldDecls: list
def __init__(self, ArchName):
self.Parsed = True
self.ArchName = ArchName
self.NamespaceScope = []
self.CurrentNamespace = ""
self.TU = None
self.Structs = {}
self.Unions = {}
self.VarDecls = {}
self.FieldDecls = []
class DBList:
DBs: list
def __init__(self, DB32, DB64, DBAArch64, DBWin32, DBWin64):
self.DBs = [DB32, DB64, DBAArch64, DBWin32, DBWin64]
def FindClangArguments(OriginalArguments):
AddedArguments = ["clang"]
AddedArguments.extend(OriginalArguments)
AddedArguments.extend(["-v", "-x", "c++", "-S", "-"])
Proc = subprocess.Popen(AddedArguments, stderr = subprocess.PIPE, stdin = subprocess.DEVNULL)
NewIncludes = []
BeginSearch = False
while True:
Line = Proc.stderr.readline().strip()
if not Line:
Proc.terminate()
break
if (Line == b"End of search list."):
BeginSearch = False
Proc.terminate()
break
if (BeginSearch == True):
NewIncludes.append("-I" + Line.decode('ascii'))
if (Line == b"#include <...> search starts here:"):
BeginSearch = True
# Add back original arguments
NewIncludes.extend(OriginalArguments)
return NewIncludes
def SetNamespace(Arch):
Arch.CurrentNamespace = ""
for Namespace in Arch.NamespaceScope:
Arch.CurrentNamespace = Arch.CurrentNamespace + Namespace + "::"
def HandleStructDeclCursor(Arch, Cursor, NameOverride = ""):
# Append namespace
CursorName = ""
StructType = Cursor.type
if (len(StructType.spelling) == 0):
CursorName = NameOverride
else:
CursorName = StructType.spelling
if (len(CursorName) != 0):
Arch.NamespaceScope.append(CursorName)
SetNamespace(Arch)
Struct = StructDefinition(
Name = CursorName,
Size = StructType.get_size())
# Handle children
Arch.Structs[Struct.Name] = HandleStructElements(Arch, Struct, Cursor)
# Pop namespace off
if (len(CursorName) != 0):
Arch.NamespaceScope.pop()
SetNamespace(Arch)
return Arch
def HandleUnionDeclCursor(Arch, Cursor, NameOverride = ""):
# Append namespace
CursorName = ""
if (len(Cursor.spelling) == 0):
CursorName = NameOverride
else:
CursorName = Cursor.spelling
if (len(CursorName) != 0):
Arch.NamespaceScope.append(CursorName)
SetNamespace(Arch)
UnionType = Cursor.type
Union = UnionDefinition(
Name = CursorName,
Size = UnionType.get_size())
Arch.Unions[Union.Name] = Union
# Handle children
Arch.Unions[Union.Name] = HandleStructElements(Arch, Union, Cursor)
# Pop namespace off
if (len(CursorName) != 0):
Arch.NamespaceScope.pop()
SetNamespace(Arch)
return Arch
def HandleVarDeclCursor(Arch, Cursor):
CursorName = Cursor.spelling
DeclType = Cursor.type
Def = Cursor.get_definition()
VarDecl = VarDeclDefinition(
Name = CursorName,
Size = DeclType.get_size())
Arch.VarDecls[VarDecl.Name] = HandleVarDeclElements(Arch, VarDecl, Cursor)
return Arch
def HandleVarDeclElements(Arch, VarDecl, Cursor):
for Child in Cursor.get_children():
if (Child.kind == CursorKind.ANNOTATE_ATTR):
if (Child.spelling.startswith("ioctl-alias-")):
Sections = Child.spelling.split("-")
if (Sections[2] == "x86_32"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_X86_32))
elif (Sections[2] == "x86_64"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_X86_64))
elif (Sections[2] == "aarch64"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_AARCH64))
elif (Sections[2] == "win32"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_WIN32))
elif (Sections[2] == "win64"):
VarDecl.Aliases.append(AliasType(Sections[3], AliasType.ALIAS_WIN64))
else:
logging.critical ("Can't handle alias type '{0}'".format(Child.spelling))
Arch.Parsed = False
elif (Child.spelling == "fex-match"):
VarDecl.ExpectFEXMatch = True
else:
# Unknown annotation
pass
elif (Child.kind == CursorKind.TYPE_REF or
Child.kind == CursorKind.UNEXPOSED_EXPR or
Child.kind == CursorKind.PAREN_EXPR or
Child.kind == CursorKind.BINARY_OPERATOR
):
pass
return VarDecl
def HandleTypeDefDeclCursor(Arch, Cursor):
TypeDefType = Cursor.underlying_typedef_type
CanonicalType = TypeDefType.get_canonical()
TypeDefName = Cursor.type.get_typedef_name()
if (TypeDefType.kind == TypeKind.ELABORATED and CanonicalType.kind == TypeKind.RECORD):
if (len(TypeDefName) != 0):
HandleTypeDefDecl(Arch, Cursor, TypeDefName)
# Append namespace
Arch.NamespaceScope.append(TypeDefName)
SetNamespace(Arch)
Arch = HandleCursor(Arch, Cursor)
#StructType = Cursor.type
#Struct = StructDefinition(
# Name = TypeDefName,
# Size = CanonicalType.get_size())
#Arch.Structs[TypeDefName] = Struct
## Handle children
#Arch.Structs[TypeDefName] = HandleStructElements(Arch, Struct, Cursor)
# Pop namespace off
Arch.NamespaceScope.pop()
SetNamespace(Arch)
else:
if (len(TypeDefName) != 0):
Def = Cursor.get_definition()
VarDecl = VarDeclDefinition(
Name = TypeDefName,
Size = CanonicalType.get_size())
Arch.VarDecls[VarDecl.Name] = HandleVarDeclElements(Arch, VarDecl, Cursor)
return Arch
def HandleStructElements(Arch, Struct, Cursor):
for Child in Cursor.get_children():
# logging.info ("\t\tStruct/Union Children: Cursor \"{0}{1}\" of kind {2}".format(Arch.CurrentNamespace, Child.spelling, Child.kind))
if (Child.kind == CursorKind.ANNOTATE_ATTR):
if (Child.spelling.startswith("alias-")):
Sections = Child.spelling.split("-")
if (Sections[1] == "x86_32"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_X86_32))
elif (Sections[1] == "x86_64"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_X86_64))
elif (Sections[1] == "aarch64"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_AARCH64))
elif (Sections[1] == "win32"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_WIN32))
elif (Sections[1] == "win64"):
Struct.Aliases.append(AliasType(Sections[2], AliasType.ALIAS_WIN64))
else:
logging.critical ("Can't handle alias type '{0}'".format(Child.spelling))
Arch.Parsed = False
elif (Child.spelling == "fex-match"):
Struct.ExpectFEXMatch = True
else:
# Unknown annotation
pass
elif (Child.kind == CursorKind.FIELD_DECL):
ParentType = Cursor.type
FieldType = Child.type
Field = FieldDefinition(
Name = Child.spelling,
Size = FieldType.get_size(),
OffsetOf = ParentType.get_offset(Child.spelling),
Alignment = FieldType.get_align())
#logging.info ("\t{0}".format(Child.spelling))
#logging.info ("\t\tSize of type: {0}".format(FieldType.get_size()));
#logging.info ("\t\tAlignment of type: {0}".format(FieldType.get_align()));
#logging.info ("\t\tOffsetof of type: {0}".format(ParentType.get_offset(Child.spelling)));
Struct.Members.append(Field)
Arch.FieldDecls.append(Field)
elif (Child.kind == CursorKind.STRUCT_DECL):
ParentType = Cursor.type
FieldType = Child.type
Field = FieldDefinition(
Name = Child.spelling,
Size = FieldType.get_size(),
OffsetOf = ParentType.get_offset(Child.spelling),
Alignment = FieldType.get_align())
#logging.info ("\t{0}".format(Child.spelling))
#logging.info ("\t\tSize of type: {0}".format(FieldType.get_size()));
#logging.info ("\t\tAlignment of type: {0}".format(FieldType.get_align()));
#logging.info ("\t\tOffsetof of type: {0}".format(ParentType.get_offset(Child.spelling)));
Struct.Members.append(Field)
Arch.FieldDecls.append(Field)
Arch = HandleStructDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.UNION_DECL):
Struct = HandleStructElements(Arch, Struct, Child)
#ParentType = Cursor.type
#FieldType = Child.type
#Field = FieldDefinition(
# Name = Child.spelling,
# Size = FieldType.get_size(),
# OffsetOf = ParentType.get_offset(Child.spelling),
# Alignment = FieldType.get_align())
#logging.info ("\t{0}".format(Child.spelling))
#logging.info ("\t\tSize of type: {0}".format(FieldType.get_size()));
#logging.info ("\t\tAlignment of type: {0}".format(FieldType.get_align()));
#logging.info ("\t\tOffsetof of type: {0}".format(ParentType.get_offset(Child.spelling)));
#Struct.Members.append(Field)
#Arch.FieldDecls.append(Field)
#Arch = HandleUnionDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.TYPEDEF_DECL):
Arch = HandleTypeDefDeclCursor(Arch, Child)
else:
Arch = HandleCursor(Arch, Child)
return Struct
def HandleTypeDefDecl(Arch, Cursor, Name):
for Child in Cursor.get_children():
if (Child.kind == CursorKind.UNION_DECL):
pass
elif (Child.kind == CursorKind.STRUCT_DECL):
Arch = HandleStructDeclCursor(Arch, Child, Name)
elif (Child.kind == CursorKind.UNION_DECL):
Arch = HandleUnionDeclCursor(Arch, Child, Name)
elif (Child.kind == CursorKind.TYPEDEF_DECL):
Arch = HandleTypeDefDeclCursor(Arch, Child)
elif (Child.kind == CursorKind.TYPE_REF or
Child.kind == CursorKind.NAMESPACE_REF or
Child.kind == CursorKind.TEMPLATE_REF or
Child.kind == CursorKind.ALIGNED_ATTR):
# Safe to pass on
pass
else:
logging.critical ("Unhandled TypedefDecl {0}-{1}-{2}".format(Child.kind, Child.type.spelling, Child.spelling))
def HandleCursor(Arch, Cursor):
if (Cursor.kind.is_invalid()):
Diags = TU.diagnostics
for Diag in Diags:
logging.warning (Diag.format())
Arch.Parsed = False
return
for Child in Cursor.get_children():
kind = Child.kind
if (kind == CursorKind.TRANSLATION_UNIT):
Arch = HandleCursor(Arch, Child)
elif (kind == CursorKind.FIELD_DECL):
pass
elif (kind == CursorKind.UNION_DECL):
Arch = HandleUnionDeclCursor(Arch, Child)
elif (kind == CursorKind.STRUCT_DECL):
Arch = HandleStructDeclCursor(Arch, Child)
elif (kind == CursorKind.TYPEDEF_DECL):
Arch = HandleTypeDefDeclCursor(Arch, Child)
elif (kind == CursorKind.VAR_DECL):
Arch = HandleVarDeclCursor(Arch, Child)
elif (kind == CursorKind.NAMESPACE):
# Append namespace
Arch.NamespaceScope.append(Child.spelling)
SetNamespace(Arch)
# Handle children
Arch = HandleCursor(Arch, Child)
# Pop namespace off
Arch.NamespaceScope.pop()
SetNamespace(Arch)
elif (kind == CursorKind.TYPE_REF):
# Safe to pass on
pass
else:
Arch = HandleCursor(Arch, Child)
return Arch
def GetDB(Arch, filename, args):
Index = clang.cindex.Index.create()
try:
TU = Index.parse(filename, args=args, options=TranslationUnit.PARSE_INCOMPLETE)
except TranslationUnitLoadError:
Arch.Parsed = False
Diags = TU.diagnostics
for Diag in Diags:
logging.warning (Diag.format())
return
Arch.TU = TU
HandleCursor(Arch, TU.cursor)
# Get diagnostics
Diags = TU.diagnostics
if (len(Diags) != 0):
logging.warning ("Diagnostics from Arch: {0}".format(Arch.ArchName))
for Diag in Diags:
logging.warning (Diag.format())
return Arch
def GetCompar(ComparisonName, DBs):
if (ComparisonName.lower() == "x86_32"):
return DBs.DBs[AliasType.ALIAS_X86_32]
elif (ComparisonName.lower() == "x86_64"):
return DBs.DBs[AliasType.ALIAS_X86_64]
elif (ComparisonName.lower() == "win32"):
return DBs.DBs[AliasType.ALIAS_WIN32]
elif (ComparisonName.lower() == "win64"):
return DBs.DBs[AliasType.ALIAS_WIN64]
elif (ComparisonName.lower() == "aarch64"):
return DBs.DBs[AliasType.ALIAS_AARCH64]
def PrintMissingMembers(Struct1, Struct2):
for Member1 in Struct1.Members:
WasMissing = True
for Member2 in Struct2.Members:
if (Member1.Name == Member2.Name):
WasMissing = False
break
if (WasMissing):
logging.error ("\t'{0}' member '{1}' Doesn't exist in '{2}'".format(Struct1.Name, Member1.Name, Struct2.Name));
def CompareStructs(Struct1, Struct2):
HadWarning = False
HadError = False
# Check if the struct size is a mismatch
if (Struct1.Size != Struct2.Size):
logging.warning ("\t#### Warning: Struct size mismatch. {0} != {1}".format(Struct1.Size, Struct2.Size))
logging.warning ("\t\tMight not be a problem if struct isn't in used inside another struct, or end of object")
HadWarning = True
# Check if the number of members differ
if (len(Struct1.Members) != len(Struct2.Members)):
logging.error ("@@@@ ERROR: Struct fields mismatch! Number of fields don't match! {0} != {1}".format(len(Struct1.Members), len(Struct2.Members)));
PrintMissingMembers(Struct1, Struct2)
PrintMissingMembers(Struct2, Struct1)
HadError = True
else:
# Compare the members themselves
for StructMemberIndex in range(0, len(Struct1.Members)):
Member1 = Struct1.Members[StructMemberIndex]
Member2 = Struct2.Members[StructMemberIndex]
if (Member1.Type == TypeDefinition.TYPE_FIELD):
if (Member1.Size != Member2.Size):
logging.error ("\t@@@@ ERROR: Member '{0}' mismatch Size! {1} != {2}".format(Member1.Name, Member1.Size, Member2.Size));
HadError = True
if (Member1.OffsetOf != Member2.OffsetOf):
logging.error ("\t@@@@ ERROR: Member '{0}' mismatch OffsetOf! {1} != {2}".format(Member1.Name, Member1.OffsetOf, Member2.OffsetOf));
HadError = True
if (Member1.Alignment != Member2.Alignment):
logging.error ("\t@@@@ ERROR: Member '{0}' mismatch Alignment! {1} != {2}".format(Member1.Name, Member1.Alignment, Member2.Alignment));
logging.error ("\t\tProbably not a problem if offset and size matches");
HadWarning = True
else:
logging.critical ("Oops, didn't handle member type {0}".format(Member1.Type))
pass
return not (HadWarning or HadError)
def CompareAliases(DB, DBs):
Passed = True
for StructKey, StructDef in DB.Structs.items():
if (len(StructKey) == 0):
# XXX: Oops, shouldn't have anonymous structs
continue
if (len(StructDef.Aliases) != 0):
logging.info ("Comparing Aliases {0}".format(StructDef.Name))
for Alias in StructDef.Aliases:
OtherDB = DBs.DBs[Alias.AliasType]
OtherStruct = OtherDB.Structs.get(Alias.Name)
if (OtherStruct == None):
logging.critical ("Couldn't find alias {0} in {1} DB".format(Alias.Name, OtherDB.ArchName))
Passed = False
continue
ThisAlias = CompareStructs(StructDef, OtherStruct)
if not (ThisAlias):
logging.error ("Couldn't Alias to Arch {0} successfully".format(OtherDB.ArchName))
Passed &= ThisAlias
for VarDeclKey, VarDecl in DB.VarDecls.items():
if (len(VarDeclKey) == 0):
# XXX: Oops, shouldn't have anonymous vardecls
continue
for Alias in VarDecl.Aliases:
OtherDB = DBs.DBs[Alias.AliasType]
OtherAlias = OtherDB.VarDecls.get(Alias.Name)
if (OtherAlias == None):
logging.critical ("Couldn't find alias {0} in {1} DB".format(Alias.Name, OtherDB.ArchName))
Passed = False
continue
if (VarDecl.Size != OtherAlias.Size):
logging.critical("VarDecl: {0}/{1} didn't match {2}/{3}: {4:08X} != {5:08X}".format(VarDeclKey, DB.ArchName, Alias.Name,
OtherDB.ArchName,
VarDecl.Size, OtherAlias.Size))
Passed = False
continue
return Passed
def CompareCrossArch(DB1, DB2):
Passed = True
for StructKey, StructDef in DB1.Structs.items():
if (len(StructKey) == 0):
# XXX: Oops, shouldn't have anonymous structs
continue
logging.info ("Comparing crossArch {0}".format(StructDef.Name))
if (StructDef.ExpectFEXMatch):
Struct2 = DB2.Structs.get(StructDef.Name)
if (Struct2 == None):
logging.critical ("Couldn't find Struct {0} in {1} DB".format(StructDef.Name, DB2.ArchName))
Passed = False
continue
Passed &= CompareStructs(StructDef, Struct2)
return Passed
def main():
if sys.version_info[0] < 3:
logging.critical ("Python 3 or a more recent version is required.")
if (len(sys.argv) < 2):
print ("usage: %s <options> <Header.hpp> <clang arguments...>" % (sys.argv[0]))
print ("\t-c1 <Type1>: Base Comparison Type");
print ("\t-c2 <Type2>: Second Comparison Type");
print ("\t-win: Parse Windows");
sys.exit ("\t-no-linux: Do not parse Linux");
ParseLinux = True
ParseWindows = False
Header = ""
Comparison1 = ""
Comparison2 = ""
BaseArgs = []
StartOfArgs = 0
# Parse our arguments
ArgIndex = 1
while ArgIndex < len(sys.argv):
Arg = sys.argv[ArgIndex]
if (Arg == "--"):
StartOfArgs = ArgIndex + 1
break;
if (Arg == "-c1"):
ArgIndex += 1
Comparison1 = sys.argv[ArgIndex]
elif (Arg == "-c2"):
ArgIndex += 1
Comparison2 = sys.argv[ArgIndex]
elif (Arg == "-win"):
ParseWindows = True
elif (Arg == "-no-linux"):
ParseLinux = False
else:
Header = Arg
StartOfArgs = ArgIndex + 1
break
# Increment
ArgIndex += 1
# Add arguments for clang
for ArgIndex in range(StartOfArgs, len(sys.argv)):
BaseArgs.append(sys.argv[ArgIndex])
args_x86_32 = [
"-isystem", "/usr/i686-linux-gnu/include",
"-O2",
"-m32",
"--target=i686-linux-unknown",
]
args_x86_64 = [
"-isystem", "/usr/x86_64-linux-gnu/include",
"-O2",
"--target=x86_64-linux-unknown",
"-DARCHITECTURE_x86_64",
]
args_aarch64 = [
"-isystem", "/usr/aarch64-linux-gnu/include",
"-O2",
"--target=aarch64-linux-unknown",
"-DARCHITECTURE_arm64",
]
args_x86_win32 = [
"-I/usr/lib/gcc/i686-w64-mingw32/10-win32/include/c++/",
"-I/usr/lib/gcc/i686-w64-mingw32/10-win32/include/c++/i686-w64-mingw32/",
"-O2",
"-m32",
"--target=i686-pc-win32",
]
args_x86_win64 = [
"-I/usr/lib/gcc/x86_64-w64-mingw32/10-win32/include/c++/",
"-I/usr/lib/gcc/x86_64-w64-mingw32/10-win32/include/c++/x86_64-w64-mingw32/",
"-O2",
"--target=x86_64-pc-win32",
]
# Add all the arguments to the different lists
args_x86_32.extend(BaseArgs)
args_x86_64.extend(BaseArgs)
args_aarch64.extend(BaseArgs)
args_x86_win32.extend(BaseArgs)
args_x86_win64.extend(BaseArgs)
# We need to find the default arguments through clang invocations
args_x86_32 = FindClangArguments(args_x86_32)
args_x86_64 = FindClangArguments(args_x86_64)
args_aarch64 = FindClangArguments(args_aarch64)
args_x86_win32 = FindClangArguments(args_x86_win32)
args_x86_win64 = FindClangArguments(args_x86_win64)
Arch_x86_32 = ArchDB("x86_32")
Arch_x86_64 = ArchDB("x86_64")
Arch_aarch64 = ArchDB("aarch64")
Arch_x86_win32 = ArchDB("win32")
Arch_x86_win64 = ArchDB("win64")
if (ParseLinux):
Arch_x86_32 = GetDB(Arch_x86_32, Header, args_x86_32)
Arch_x86_64 = GetDB(Arch_x86_64, Header, args_x86_64)
Arch_aarch64 = GetDB(Arch_aarch64, Header, args_aarch64)
if not (Arch_x86_32.Parsed):
logging.critical ("Couldn't parse:{0}".format(Arch_x86_32.ArchName))
if not (Arch_x86_64.Parsed):
logging.critical ("Couldn't parse:{0}".format(Arch_x86_64.ArchName))
if not (Arch_aarch64.Parsed):
logging.critical ("Couldn't parse:{0}".format(Arch_aarch64.ArchName))
if (ParseWindows):
Arch_x86_win32 = GetDB(Arch_x86_win32, Header, args_x86_win32)
Arch_x86_win64 = GetDB(Arch_x86_win64, Header, args_x86_win64)
if not (Arch_x86_win32.Parsed):
logging.critical ("Couldn't parse:{0}".format(Arch_x86_win32.ArchName))
if not (Arch_x86_win64.Parsed):
logging.critical ("Couldn't parse:{0}".format(Arch_x86_win64.ArchName))
DBs = DBList(Arch_x86_32,
Arch_x86_64,
Arch_aarch64,
Arch_x86_win32,
Arch_x86_win64)
Result = 0
if (len(Comparison1) != 0 and len(Comparison2) != 0):
CompDB1 = GetCompar(Comparison1, DBs)
CompDB2 = GetCompar(Comparison2, DBs)
# Now compare across the two compared architectures
Result = 0 if CompareCrossArch(CompDB1, CompDB2) else 1
elif (len(Comparison1) != 0):
CompDB1 = GetCompar(Comparison1, DBs)
# First compare the aliases to make sure we are matching
Result = 0 if CompareAliases(CompDB1, DBs) else 1
if (Result == 1):
logging.error("Execution environment")
Args = "[ "
for Arg in sys.argv:
Args += Arg + ", "
Args += " ]"
logging.error(Args)
Args = ""
for Arg in sys.argv:
Args += "\"" + Arg + "\" "
logging.error(Args)
return Result
if __name__ == "__main__":
# execute only if run as a script
sys.exit(main())