Refactor Yokai system and architecture detection, detect architecture cross-compilation, extend architecture detection#1987
Refactor Yokai system and architecture detection, detect architecture cross-compilation, extend architecture detection#1987illwieckz wants to merge 4 commits into
Conversation
df79f28 to
b8b0a34
Compare
| "arm" | ||
| ) | ||
| if ("${arch_name}" STREQUAL "${name}") | ||
| message(STATUS "Parent architecture: ${name}, can be ${AMBIGUOUS_${name}}") |
There was a problem hiding this comment.
Where is the "AMBIGUOUS" variable supposed to come from?
There was a problem hiding this comment.
Ah right, I missed this part after renaming ${AMBIGUOUS_${name}} into ${${name}_CHILD} before squashing my WIP commits.
|
|
||
| foreach(child_name ${${name}_CHILD}) | ||
| string(TOUPPER "${child_name}" child_name_upper) | ||
| set(YOKAI_HOST_ARCH_${child_name_upper}_PARENT ON PARENT_SCOPE) |
There was a problem hiding this comment.
What is this variable supposed to signal?
There was a problem hiding this comment.
When YOKAI_HOST_ARCH_arm is true, then both YOKAI_HOST_ARCH_armhf_PARENT and YOKAI_HOST_ARCH_armel_PARENT are true. So when either YOKAI_TARGET_ARCH_armel_PARENT or YOKAI_TARGET_ARCH_armhf_PARENT is true we can make the assumption that we're not cross-compiling.
It's impossible to tell the ABI (armel, armhf) from uname -m (what basically CMake uses as a backend here) and the difference is mostly a compiler flag. So it's more prudent to assume it's not a cross-compilation. Guessing the host ABI would require to check what is the default ELF loader, for now I don't see the need to go this deeper (and it would be overly specific to the system… so overly complex).
Such deeper need may surface when building a host tool to run it (in fact building such host tool the static way would keep it runnable in that case), but we explicitly avoid to build and run host tool in CMake and Yokai itself is designed to avoid that for its own needs and we encourage to not do that.
b8b0a34 to
9d5e194
Compare
| if ("${arch_name}" STREQUAL "unknown") | ||
| set(ARCH_em64t "amd64") | ||
| set(ARCH_x86_64 "amd64") | ||
| set(ARCH_armv7l, "arm") |
There was a problem hiding this comment.
Commas probably shouldn't be there?
| "amd64" | ||
| "arm" | ||
| ) | ||
| if ("${ARCH_${processor_lower}}" STREQUAL "${name}") |
There was a problem hiding this comment.
This code seems to say that out of the preceding long list only the ARM ones matter. Maybe you just wanted to check whether an ARCH_${processor_lower} variable was non-empty?
There was a problem hiding this comment.
If uname -m prints x86_64, then CMAKE_HOST_SYSTEM_PROCESSOR is x86_64 and processor_lower is also x86_64. Since ARCH_x86_64 contains amd64, then ${ARCH_${processor_lower}} equals amd64, so arch_name is set to amd64.
This is an equivalent of (in shell):
case "$(uname -m)" in
'x86_64') arch_name='amd64';;
'armv6l'|'armv7l') arch_name='arm';;
'aarch64') arch_name='arm64';;
esacIt's probably possible to rewrite it this way:
set(ARCHES_amd64 "x86_64")
set(ARCHES_arm "armv6l" "armv7l")
set(ARCHES_arm64 "aarch64")
foreach(name
"amd64"
"arm"
"arm64"
)
if ("${processor_lower}" IN_LIST ARCHES_${name})
set(arch_name "${name}")
endif()
endforeach()Which would be equivalent to (in python):
arches = {
"amd64": ["x86_64"],
"arm": ["armv6l", "armv7l"],
"arm64": ["aarch64"],
}
for arch in arches.keys():
if process_lower in arches[arch]:
arch_name = archBut we don't need two loops.
Actually in my code I forgot to list some values to check for, and I could say:
- set(arch_name "${ARCH_${processor_lower}}")
+ set(arch_name "${name}")Now done.
There was a problem hiding this comment.
If you prefer, I pushed that “dictionary of list” alternative, it this loops more (IN_LIST inside foreach), but that may be preferred for readability:
set(ARCHES_amd64 "em64t" "x86_64")
set(ARCHES_arm "armv6l" "armv7l")
set(ARCHES_arm64 "aarch64")
set(ARCHES_loong64 "loongarch64")
set(ARCHES_ppc64el "ppc64le")
foreach(name
"amd64"
"arm"
"arm64"
"loong64"
"ppc64el"
)
if ("${processor_lower}" IN_LIST ARCHES_${name})
set(arch_name "${name}")
endif()
endforeach()There was a problem hiding this comment.
It's also possible to do that for extra constraints, but that may be overkill 🤣️:
macro(list_dict_add dict_name key_name)
list(APPEND ${dict_name}_keys ${key_name})
set(key_values "${ARGN}")
foreach(key_value IN LISTS key_values)
list(APPEND ${dict_name}_${key_name} ${key_value})
endforeach()
endmacro()
macro(copy_key_from_list_dict dict_name searched_value output_name)
foreach(key_name IN LISTS ${dict_name}_keys)
if ("${searched_value}" IN_LIST ${dict_name}_${key_name})
set(${output_name} "${key_name}")
endif()
endforeach()
endmacro()
list_dict_add("ARCHES" "amd64" "em64t" "x86_64")
list_dict_add("ARCHES" "arm" "armv6l" "armv7l")
list_dict_add("ARCHES" "arm64" "aarch64")
list_dict_add("ARCHES" "loong64" "loongarch64")
list_dict_add("ARCHES" "ppc64el" "ppc64le")
copy_key_from_list_dict("ARCHES" "${processor_lower}" "arch_name")Or even, for even more constraints 🤣️🤣️🤣️:
macro(list_dict_set dict_name)
set(DICT_name "${dict_name}")
endmacro()
macro(list_dict_add key_name)
list(APPEND ${DICT_name}_keys ${key_name})
set(key_values "${ARGN}")
foreach(key_value IN LISTS key_values)
list(APPEND ${DICT_name}_${key_name} ${key_value})
endforeach()
endmacro()
macro(copy_key_from_list_dict searched_value output_name)
foreach(key_name IN LISTS ${DICT_name}_keys)
if ("${searched_value}" IN_LIST ${DICT_name}_${key_name})
set(${output_name} "${key_name}")
endif()
endforeach()
endmacro()
list_dict_set("ARCHES")
list_dict_add("amd64" "em64t" "x86_64")
list_dict_add("arm" "armv6l" "armv7l")
list_dict_add("arm64" "aarch64")
list_dict_add("loong64" "loongarch64")
list_dict_add("ppc64el" "ppc64le")
copy_key_from_list_dict("${processor_lower}" "arch_name")2888937 to
b93ae4b
Compare
1a3972a to
c69802e
Compare
qprocessordetection.hfrom Qt upstream and recognizeloong64.The Loongsoon architecture is one of the architectures supported by
box64, so it's likely possible to run Unvanquished on it (likeppc64elandriscv64).Unify the woridng of the code, and better code in general, also fixes some edge cases Unvanquished/Dæmon wasn't triggering.
Makes possible to detect when cross-compiling from one architecture to another on the same system.
I started using Yokai in a local branch of the Saigo release scripts and I noticed a linking bug happening on FreeBSD when cross-compiling a 32-bit binutils on a 64-bit system (classic
-L/usr/lib32thing). I finally fixed that by patching binutils, but that's a proof it is useful to detect that the target architecture differs from the host target.