Skip to content

cmake: make DaemonPlatform, Architecture, Compiler, etc. autonomous and reusable as Yokai framework#1641

Open
illwieckz wants to merge 26 commits into
masterfrom
illwieckz/cmake-platform
Open

cmake: make DaemonPlatform, Architecture, Compiler, etc. autonomous and reusable as Yokai framework#1641
illwieckz wants to merge 26 commits into
masterfrom
illwieckz/cmake-platform

Conversation

@illwieckz

@illwieckz illwieckz commented Apr 7, 2025

Copy link
Copy Markdown
Member

Some revamp of the DaemonPlatform/DaemonArchitecture/DaemonCompiler/DaemonBuildInfo helper code for CMake.

I want this framework to be reusable for other projects, the first user outside of the engine may be the NaCl loader itself, and I may use it for NetRadiant as well at some point. So I made the code fully autonomous and contained in a single folder (so it can be copied and kept it sync easily).

It happens that the endian stuff we did in the DaemonCompiler code using Endian.h was useless (it was not doing better than what the qprocessordetection.h code does anyway), so I removed it.

I also renamed GAME_PIE to NACL_PIE because it's an NaCl option, it was named GAME_PIE because we only build games as NaCl, but for a self-contained framework we better name the NaCl option NACL. For now this code sets GAME_PIE to the NACL_PIE value but once the game is modified to use NACL_PIE the code setting the GAME_PIE alias will be deleted.


Edit: That framework now has its own name: Yokai.

Yokai is the name of that reusable generic CMake framework. CMake variables are prefixed with YOKAI_, C variables and definitions are prefixed with YOKAI_ as well, and the folder for generated files is prefixed with Yokai.

The name is inspired from that third race mod that was named Unvanquished, from which we already inherited the Dæmon name (Dæmon was the third team name along Humans and Aliens, the Yokai model was one of those Dæmons).

@slipher

slipher commented Apr 8, 2025

Copy link
Copy Markdown
Member

Why would we need a variable called NACL_PIE? There is no PIE for NaCl and never will be.

@slipher

slipher commented Oct 9, 2025

Copy link
Copy Markdown
Member

I want this framework to be reusable for other projects

Note that some of the facilities here duplicate CMake built-in functionality, or have more fully developed alternatives available from other projects. Effort is likely to be wasted in such cases:

  • For daemon_write_generated(file.cpp ${contents}), CMake's file(GENERATED OUTPUT file.cpp CONTENTS ${contents}) is a drop-in replacement, modulo daemon_write_generated adding stuff to the path name. See the slipher/cmake-filegenerated branch.
  • The build info stuff largely duplicates the functionality of CMake's configure_file.
  • For a platform-independent resource compiler implemented as CMake script / embedding files (though that's not actually part of this PR currently), there is https://github.com/vector-of-bool/cmrc

DaemonArchitecture looks most likely to be useful. I think I saw a similar thing with SDL, but Daemon's looked more complete.

@slipher

slipher commented Oct 12, 2025

Copy link
Copy Markdown
Member

Why would we need a variable called NACL_PIE? There is no PIE for NaCl and never will be.

Well maybe I'm wrong about that: the native_client scons build has a nacl_pic option. It has an effect only for PNaCl toolchains, not Saigo.

@slipher

slipher commented Oct 12, 2025

Copy link
Copy Markdown
Member

Then again, there is a comment explaining that it is not useful:

# Since PNaCl has no reason to generate PIC at all until there is some
# form of ELF shared object support (if that ever happens at all),
# perhaps we'll never really need to test this.

Also there is another comment confirming that Saigo does not have PIC.

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 2 times, most recently from 745bede to d2b73ca Compare December 9, 2025 06:37
@illwieckz

Copy link
Copy Markdown
Member Author

I removed the unused NaCl PIE thing.

@illwieckz illwieckz changed the title cmake: make DaemonPlatform/Architecture/Compiler/BuildInfo autonomous and reusable cmake: make DaemonPlatform, Architecture, Compiler, etc. autonomous and reusable Dec 9, 2025
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 3 times, most recently from f01bf1f to 10ae04b Compare December 9, 2025 10:06
Comment thread cmake/Yokai/All.cmake
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 2 times, most recently from 5d31fb8 to a9191be Compare December 16, 2025 08:54
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from a9191be to cd64470 Compare December 16, 2025 11:19
@illwieckz

Copy link
Copy Markdown
Member Author

I landed my rewrite of System.cmake that does like Compiler.cmake to detect the target system.

This defines variables like DAEMON_HOST_SYSTEM and DAEMON_TARGET_SYSTEM.

A good example of usage of them is to avoid the ambiguity of WIN32.

Instead of WIN32 to detect the target we can use DAEMON_TARGET_SYSTEM_Windows and instead of MSVC and NOT MSVC AND WIN32 to detect the compiler we can use DAEMON_CXX_COMPILER_MSVC and DAEMON_CXX_COMPILER_MinGW.

It may also help to do things differently with MinGW on Linux and MinGW on Windows, when needed.

It may also help in the future as cross-compiler evolves, for example the day Zig becomes suitable for us to cross-compile for macOS on Linux, and things like that.

I also renamed ARCH and NACL_ARCH as DAEMON_ARCH and DAEMON_NACL_ARCH, as I prefer those global variable to be prefixed with DAEMON, especially since I write that DamonPlatform things to be reusable outside of the engine, and short names like ARCH are likely to collide.

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 5 times, most recently from 3227432 to 5712ef4 Compare December 16, 2025 16:21
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 6 times, most recently from 6bfb4db to 95c6284 Compare June 9, 2026 02:33
@illwieckz

Copy link
Copy Markdown
Member Author

The NaCl architecture stuff is now removed from Yokai and stored in cmake/DaemonNaclHost.cmake, it is only called by the engine CMake code. Note that I will probably deeply rewrite this code later, but that's outside of the scope if this PR.

@illwieckz

Copy link
Copy Markdown
Member Author

(Also I think it's bad how build info is done with gamelogic currently, though that can go in another PR. DaemonGame.cmake currently generates the build info when it's included and then it's hackily included from q_shared.h with ifdefs. Instead of that, the gamelogic should call daemon_generate_buildinfo itself (if it even wants to) and include it from its own files: that way it would have the chance to add its own definitions.)

Right now Dæmon's CMakeLists.txt does:

yokai_write_buildinfo("DaemonEngine")

And game's DaemonGame.cmake does:

yokai_write_buildinfo("DaemonGame")

The buildinfo is never mixed between engine and game.

@illwieckz

illwieckz commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

The buildinfo is never mixed between engine and game.

Also the list of things in engine and game buildinfo aren't the same anymore, for example the game buildinfo doesn't have the DAEMON_NACL_ARCH_STRING constant that is engine-only.

Also it's not possible for the game to use engine's buildinfo because the nexe build is done in a subfolder.

The name passed to yokai_write_buildinfo is the name of the subfoler the buildinfo data is written to, to make sure the game doesn't reuse engine buildinfo by mistake when built as dll/exe (and sharing the build folder with the engine).

@slipher

slipher commented Jun 9, 2026

Copy link
Copy Markdown
Member

(Also I think it's bad how build info is done with gamelogic currently, though that can go in another PR. DaemonGame.cmake currently generates the build info when it's included and then it's hackily included from q_shared.h with ifdefs. Instead of that, the gamelogic should call daemon_generate_buildinfo itself (if it even wants to) and include it from its own files: that way it would have the chance to add its own definitions.)

Right now Dæmon's CMakeLists.txt does:

yokai_write_buildinfo("DaemonEngine")

And game's DaemonGame.cmake does:

yokai_write_buildinfo("DaemonGame")

The buildinfo is never mixed between engine and game.

I'm saying the write_buildinfo should be in Unvanquished CMakeLists.txt, not in DaemonGame.cmake. I'm hoping this could fix #1599.

#endif

#if defined(__unix__) || defined(__unix) || defined(unix)
#pragma message(REPORT_COMPATIBILITY("Unix"))

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.

I suggest removing this as it has unexpected semantics: Mac OS is a Unix, but does not define these. Anyhow the good old idiom for Unix-like is NOT WIN32 :)

Comment thread cmake/Yokai/System.cmake Outdated
# implementing standards like FHS, XDG, GLVND…
# Makes possible to do that in CMake code:
# > if (YOKAI_HOST_SYSTEM_XDG_COMPATIBILITY)
# > if (YOKAI_SYSTEM_XDG_COMPATIBILITY)

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.

Instead of XDG_COMPATIBILITY I prefer the GNU_COMPATIBILITY name you used in some other places. This makes sense by reflecting the "GNU/Linux" userland/kernel distinction. So we have Linux compatibility include Android's Linux-based kernel, and GNU compatibility including the FreeBSD using a similar userland to the Linux desktops.

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.

Well it's not that great since GNU compatibility could also be confused for the "GNU compiler id" that CMake identifier for GCC. But at least it relates to the "GNU/Linux" meme. For me XDG doesn't suggest the concept you want to get at at all.

@illwieckz illwieckz Jun 9, 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.

In some iterations I wrote GNU too, then switched to XDG. The thing is that GNU means GNU Hurd in System context.

One may say that GNU Linux is probably similar to GNU Hurd, not less then FreeBSD, but well…

The SYSTEM_GNU_COMPATIBILITY in some other places are leftovers remaining from that first iteration I failed to clean-up properly. I'll fix it.

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.

Comment thread cmake/DaemonNaclHost.cmake Outdated
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from 95c6284 to 813b85c Compare June 9, 2026 14:14
@illwieckz

Copy link
Copy Markdown
Member Author

I should mention that besides the Clang that pretends to be MSVC, there is also Clang that pretends to be MinGW. I don't have it installed currently so I can't say how the compiler is detected.

Right now this does:

#elif defined(__MINGW64__) || defined(__MINGW32__)
	#pragma message(REPORT_NAME("MinGW"))
#elif defined(__clang__)
	#pragma message(REPORT_NAME("Clang"))

And this doesn't do any:

#pragma message(REPORT_COMPATIBILITY("MinGW"))

So for now I expect it to just be reported as COMPILER_MINGW with COMPILER_CLANG_COMPATIBILITY.

If needed we can make it be reported as COMPILER_CLANG with COMPILER_MINGW_COMPATIBILITY instead, or something like that.

One can use the Yokai/Detection/detect script for a quick preview of what CMake is expected to provide:

$ ./cmake/Yokai/Detection/detect clang
YOKAI_C_COMPILER_GCC_COMPATIBILITY=ON
YOKAI_C_COMPILER_GCC_VERSION=4.2.1
YOKAI_C_COMPILER_CLANG_COMPATIBILITY=ON
YOKAI_C_COMPILER_CLANG_VERSION=18.1.3
YOKAI_C_COMPILER_CLANG_VERSION_STRING=18.1.3 (1)
YOKAI_C_COMPILER_GENERIC_VERSION_STRING=Ubuntu Clang 18.1.3 (1)
YOKAI_C_COMPILER_NAME=Clang
YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY=ON
YOKAI_TARGET_SYSTEM_UNIX_COMPATIBILITY=ON
YOKAI_TARGET_SYSTEM_NAME=Linux
YOKAI_TARGET_ARCH_NAME=amd64

$ ./cmake/Yokai/Detection/detect aarch64-linux-android29-clang
YOKAI_C_COMPILER_GCC_COMPATIBILITY=ON
YOKAI_C_COMPILER_GCC_VERSION=4.2.1
YOKAI_C_COMPILER_CLANG_COMPATIBILITY=ON
YOKAI_C_COMPILER_CLANG_VERSION=9.0.8
YOKAI_C_COMPILER_CLANG_VERSION_STRING=9.0.8 (https://android.googlesource.com/toolchain/llvm-project 207d7abc1a2abf3ef8d4301736d6a7ebc224a290)
YOKAI_C_COMPILER_GENERIC_VERSION_STRING=4.2.1 Compatible Android (5900059 based on r365631c) Clang 9.0.8 (https://android.googlesource.com/toolchain/llvm-project 207d7abc1a2abf3ef8d4301736d6a7ebc224a290)
YOKAI_C_COMPILER_NAME=Clang
YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY=ON
YOKAI_TARGET_SYSTEM_UNIX_COMPATIBILITY=ON
YOKAI_TARGET_SYSTEM_NAME=Android
YOKAI_TARGET_ARCH_NAME=arm64

$ ./cmake/Yokai/Detection/detect i686-w64-mingw32-gcc
YOKAI_C_COMPILER_GCC_COMPATIBILITY=ON
YOKAI_C_COMPILER_GCC_VERSION=13.0.0
YOKAI_C_COMPILER_GENERIC_VERSION_STRING=13-posix
YOKAI_C_COMPILER_NAME=MinGW
YOKAI_TARGET_SYSTEM_NAME=Windows
YOKAI_TARGET_ARCH_NAME=i686

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 4 times, most recently from 4ce1846 to 726fb11 Compare June 9, 2026 17:12
@illwieckz illwieckz changed the title cmake: make DaemonPlatform, Architecture, Compiler, etc. autonomous and reusable cmake: make DaemonPlatform, Architecture, Compiler, etc. autonomous and reusable as Yokai framework Jun 9, 2026
Comment thread cmake/Yokai/Detection.cmake Outdated
PARENT_SCOPE)
endforeach()
endif()
yokai_run_detection("${lang}" "COMPILER" "Compiler${${lang}_EXT}" "GCC;Clang;generic")

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.

"generic" string seems to be unused

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 exports compiler's __VERSION__ macro to YOKAI_C_COMPILER_GENERIC_VERSION_STRING.

This is used (named as temporary variable compiler_generic_version_string in yokai_detect_compiler function) to extract the PNaCl version string.

Comment thread cmake/DaemonFlags.cmake Outdated
endif()

if (NACL AND USE_NACL_SAIGO AND SAIGO_ARCH STREQUAL "arm")
if (YOKAI_TARGET_SYSTEM_NACL AND USE_NACL_SAIGO AND YOKAI_NACL_ARCH_armhf)

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.

missed capitalization spot?

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.

Comment thread cmake/DaemonFlags.cmake Outdated
if (YOKAI_CXX_COMPILER_ICC)
set(GCC_GENERIC_ARCH "pentium4")
elseif (DAEMON_CXX_COMPILER_Zig)
elseif (YOKAI_CXX_COMPILER_Zig)

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.

missed capitalization spot?

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.

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from 726fb11 to cf3e784 Compare June 10, 2026 19:47
@slipher

slipher commented Jun 10, 2026

Copy link
Copy Markdown
Member

Will these commits be squashed?

There's one outstanding comment about the UNIX_COMPATIBILITY variable having bad semantics.

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from cf3e784 to 728e37c Compare June 10, 2026 22:10
@illwieckz

Copy link
Copy Markdown
Member Author

Will these commits be squashed?

They are fine as they are right now. Every time a mistake has been found, I applied the fix to the earliest commit, fixing the rebase all the way up, in order for every commit to be correct. The only commit I didn't do that yet was the cmake: fix a saigo armhf typo and I now done it. Each commits are autonomous and evolving the stuff step by step.

There's one outstanding comment about the UNIX_COMPATIBILITY variable having bad semantics.

The remaining generated UNIX_COMPATIBILITY variable just means #if defined(__unix__) || defined(__unix) || defined(unix).

@slipher

slipher commented Jun 10, 2026

Copy link
Copy Markdown
Member

The remaining generated UNIX_COMPATIBILITY variable just means #if defined(__unix__) || defined(__unix) || defined(unix).

And that's bad because Mac is a Unix platform but doesn't define those.

@slipher

slipher commented Jun 10, 2026

Copy link
Copy Markdown
Member

This comment: #1641 (comment)

@illwieckz

Copy link
Copy Markdown
Member Author

The remaining generated UNIX_COMPATIBILITY variable just means #if defined(__unix__) || defined(__unix) || defined(unix).

And that's bad because Mac is a Unix platform but doesn't define those.

Are you sure? I don't have an easily accessed mac next to me right now, but if you have one it's easy to check by doing:

echo '' | cc -dM -E -

If macOS doesn't define those then it explicitly refuses to be recognized as an Unix platform and we should respect that…

It borrows things from earlier MacOS, some BSD Unix stuff, GNU, NextSTEP and other things. Pre-installing a 20 years old bash (even not used as shell by default) doesn't make something an Unix. =)

@slipher

slipher commented Jun 10, 2026

Copy link
Copy Markdown
Member

Are you sure? I don't have an easily accessed mac next to me right now, but if you have one it's easy to check by doing:

echo '' | cc -dM -E -

I confirm that none of the Unix defines appear from this command.

If macOS doesn't define those then it explicitly refuses to be recognized as an Unix platform and we should respect that…

https://www.opengroup.org/openbrand/certificates/1205p.pdf

Mac OS is universally recognized as a Unix-like system. You have said that the names are intended to be understood without reading anything, so it behooves us not to make one that directly contradicts its usual understanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants