Skip to content

Refactor Yokai system and architecture detection, detect architecture cross-compilation, extend architecture detection#1987

Open
illwieckz wants to merge 4 commits into
masterfrom
illwieckz/yokai
Open

Refactor Yokai system and architecture detection, detect architecture cross-compilation, extend architecture detection#1987
illwieckz wants to merge 4 commits into
masterfrom
illwieckz/yokai

Conversation

@illwieckz

Copy link
Copy Markdown
Member
  • Update qprocessordetection.h from Qt upstream and recognize loong64.
    The Loongsoon architecture is one of the architectures supported by box64, so it's likely possible to run Unvanquished on it (like ppc64el and riscv64).
  • Rework the architecture and system detection.
    Unify the woridng of the code, and better code in general, also fixes some edge cases Unvanquished/Dæmon wasn't triggering.
  • Detect host architecture.
    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/lib32 thing). 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.

@illwieckz illwieckz added T-Improvement Improvement for an existing feature A-Build labels Jul 1, 2026
Comment thread cmake/Yokai/Architecture.cmake Outdated
"arm"
)
if ("${arch_name}" STREQUAL "${name}")
message(STATUS "Parent architecture: ${name}, can be ${AMBIGUOUS_${name}}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the "AMBIGUOUS" variable supposed to come from?

@illwieckz illwieckz Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, I missed this part after renaming ${AMBIGUOUS_${name}} into ${${name}_CHILD} before squashing my WIP commits.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


foreach(child_name ${${name}_CHILD})
string(TOUPPER "${child_name}" child_name_upper)
set(YOKAI_HOST_ARCH_${child_name_upper}_PARENT ON PARENT_SCOPE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this variable supposed to signal?

@illwieckz illwieckz Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread cmake/Yokai/Architecture.cmake Outdated
if ("${arch_name}" STREQUAL "unknown")
set(ARCH_em64t "amd64")
set(ARCH_x86_64 "amd64")
set(ARCH_armv7l, "arm")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commas probably shouldn't be there?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Now fixed.

Comment thread cmake/Yokai/Architecture.cmake Outdated
"amd64"
"arm"
)
if ("${ARCH_${processor_lower}}" STREQUAL "${name}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@illwieckz illwieckz Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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';;
esac

It'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 = arch

But 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.

@illwieckz illwieckz Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()

@illwieckz illwieckz Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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")

@illwieckz illwieckz force-pushed the illwieckz/yokai branch 2 times, most recently from 2888937 to b93ae4b Compare July 2, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Build T-Improvement Improvement for an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants