Skip to content

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

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

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

Conversation

@illwieckz
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.

@slipher
Copy link
Copy Markdown
Member

slipher commented Apr 8, 2025

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

@slipher
Copy link
Copy Markdown
Member

slipher commented Oct 9, 2025

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
Copy link
Copy Markdown
Member

slipher commented Oct 12, 2025

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
Copy link
Copy Markdown
Member

slipher commented Oct 12, 2025

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
# Collection of reusable CMake helpers written for the Dæmon engine and related
# projects.
################################################################################

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.

Why do we need this file? Are some of the files dependent on each other and so have to be included in a specific order?

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.

We need to include them in specific order, and the Compiler stuff (and maybe other things) are writing constants (like compiler name and version) that is generated as source with SourceGenerator to be embedded in the binary.

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.

Also Architecture requires System to be included first so it can select amd64 as NACL_ARCH on arm64 macOS, and things like that.

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.

Could we use this instead? https://cmake.org/cmake/help/v3.17/command/include_guard.html
Then each file can include its own dependencies and the user does not need to take care to call them in a special order.

Copy link
Copy Markdown
Member Author

@illwieckz illwieckz Dec 16, 2025

Choose a reason for hiding this comment

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

You'll end up loading them anyway.

The only thing that seems to be interesting to do is to provide an option to not generate the source files with the various discovered things, for projects not caring about reporting the build environment to the user. For example we don't need such reporting in NaCl.

Copy link
Copy Markdown
Member Author

@illwieckz illwieckz Dec 16, 2025

Choose a reason for hiding this comment

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

With the latest version, if you only include Detection.cmake without having included SourceGenerator.cmake first (or the Platform.cmake entry point which is meant to include everything supported), then no source is generated when detecting the build environment.

@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
Copy link
Copy Markdown
Member Author

There is now a unique DaemonPlatform/Detection/detect script that can be used to test the compilation-based detection outside of CMake:

$ ./detect clang
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=4.2.1
DAEMON_COMPILER_Clang_COMPATIBILITY=ON
DAEMON_COMPILER_Clang_VERSION=18.1.3
DAEMON_COMPILER_Clang_VERSION_STRING=18.1.3 (1ubuntu1)
DAEMON_COMPILER_generic_VERSION_STRING=Ubuntu Clang 18.1.3 (1ubuntu1)
DAEMON_COMPILER_NAME=Clang
DAEMON_SYSTEM_Linux_COMPATIBILITY=ON
DAEMON_SYSTEM_Unix_COMPATIBILITY=ON
DAEMON_SYSTEM_NAME=Linux
DAEMON_ARCH_NAME=amd64
$ ./detect i686-w64-mingw32-gcc
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=13.0.0
DAEMON_COMPILER_generic_VERSION_STRING=13-posix
DAEMON_COMPILER_NAME=MinGW
DAEMON_SYSTEM_NAME=Windows
DAEMON_ARCH_NAME=i686
$ ./detect arm-nacl-clang
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=4.2.1
DAEMON_COMPILER_Clang_COMPATIBILITY=ON
DAEMON_COMPILER_Clang_VERSION=21.0.0
DAEMON_COMPILER_Clang_VERSION_STRING=21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_generic_VERSION_STRING=Clang 21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_NAME=Saigo
DAEMON_SYSTEM_Unix_COMPATIBILITY=ON
DAEMON_SYSTEM_NAME=NaCl
DAEMON_ARCH_NAME=nacl

@illwieckz
Copy link
Copy Markdown
Member Author

illwieckz commented Dec 16, 2025

Actually I noticed that we can report the native architecture built with Saigo (since Saigo does direct-to-nexe):

$ ./detect pnacl-clang
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=4.2.1
DAEMON_COMPILER_Clang_COMPATIBILITY=ON
DAEMON_COMPILER_Clang_VERSION=3.6.0
DAEMON_COMPILER_Clang_VERSION_STRING=3.6.0 (https://chromium.googlesource.com/a/native_client/pnacl-clang.git 96b3da27dcefc9d152e51cf54280989b2206d789) (https://chromium.googlesource.com/a/native_client/pnacl-llvm.git d0089f0b008e03cfd141f05c80e3b628c2df75c1)
DAEMON_COMPILER_generic_VERSION_STRING=4.2.1 Compatible Clang 3.6.0 (https://chromium.googlesource.com/a/native_client/pnacl-clang.git 96b3da27dcefc9d152e51cf54280989b2206d789) (https://chromium.googlesource.com/a/native_client/pnacl-llvm.git d0089f0b008e03cfd141f05c80e3b628c2df75c1)
DAEMON_COMPILER_NAME=PNaCl
DAEMON_SYSTEM_Unix_COMPATIBILITY=ON
DAEMON_SYSTEM_NAME=NaCl
DAEMON_ARCH_NAME=pnacl
$ ./detect arm-nacl-clang
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=4.2.1
DAEMON_COMPILER_Clang_COMPATIBILITY=ON
DAEMON_COMPILER_Clang_VERSION=21.0.0
DAEMON_COMPILER_Clang_VERSION_STRING=21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_generic_VERSION_STRING=Clang 21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_NAME=Saigo
DAEMON_SYSTEM_Unix_COMPATIBILITY=ON
DAEMON_SYSTEM_NAME=NaCl
DAEMON_ARCH_NAME=armhf
$ ./detect i686-nacl-clang
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=4.2.1
DAEMON_COMPILER_Clang_COMPATIBILITY=ON
DAEMON_COMPILER_Clang_VERSION=21.0.0
DAEMON_COMPILER_Clang_VERSION_STRING=21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_generic_VERSION_STRING=Clang 21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_NAME=Saigo
DAEMON_SYSTEM_Unix_COMPATIBILITY=ON
DAEMON_SYSTEM_NAME=NaCl
DAEMON_ARCH_NAME=i686
$ ./detect x86_64-nacl-clang
DAEMON_COMPILER_GCC_COMPATIBILITY=ON
DAEMON_COMPILER_GCC_VERSION=4.2.1
DAEMON_COMPILER_Clang_COMPATIBILITY=ON
DAEMON_COMPILER_Clang_VERSION=21.0.0
DAEMON_COMPILER_Clang_VERSION_STRING=21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_generic_VERSION_STRING=Clang 21.0.0git (https://chromium.googlesource.com/native_client/nacl-llvm-project-v10.git 9c7f0369cfdd591e580c5ccfc1f00fedee58029f)
DAEMON_COMPILER_NAME=Saigo
DAEMON_SYSTEM_Unix_COMPATIBILITY=ON
DAEMON_SYSTEM_NAME=NaCl
DAEMON_ARCH_NAME=amd64

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from 3c3ea82 to 1ed9ae1 Compare December 16, 2025 20:36
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch 6 times, most recently from 3cbaa2e to 6eecf0a Compare December 18, 2025 12:35
@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from 6eecf0a to a9cb80e Compare April 7, 2026 05:25
@illwieckz
Copy link
Copy Markdown
Member Author

I rebased on current master.

@illwieckz
Copy link
Copy Markdown
Member Author

As a side quest, I'm questioning the prefix. I wanted the variables produced by this framework to have a single prefix to 1. make it obvious it's generated by the framework, 2. have them share a namespace, 3. have them explicitly different with stock CMAKE_ prefixed variables. Now, the DAEMON_ prefix may not be the best, as we have genuine need for DAEMON_ prefixed variables that don't need to be generated by this framework.

The thing is that I want this framework reusable. I plan to use it for the NaCl loader, I want to use it in NetRadiant, I may use it in XQF if the need arise. In those context, another name would be fine, though DAEMON_ isn't bad because anyway it's the framework from Dæmon, but then it may look better if that's more obvious it's the platform than the engine itself. For example DPLATFORM_ would also work.

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from a9cb80e to 49f356c Compare June 2, 2026 21:14
@illwieckz
Copy link
Copy Markdown
Member Author

@slipher I would like to merge this so I can move on. Also I need to rebase the NaCl loader cmake code above it.

In the future I may find a more generic prefix than DAEMON_ but for now it's good enough. If you think DPLATFORM_ is fine or you have a better suggestion, I may do it. I still think it would be good if things from that platform would have a prefix different to the engine-specific stuff prefixed with DAEMON_. Actually we may go the bold way with a specific name (like Sloth, Urcheon…) for example to reuse some name historically associated with the Unvanquished project: YOKAI_.

@illwieckz
Copy link
Copy Markdown
Member Author

illwieckz commented Jun 4, 2026

Actually I just did that. This CMake framework was written for the Dæmon engine first but isn't specific to the engine and is meant to be reusable for any CMake-based project, like the NaCl loader, NetRadiant, etc.

So I gave it a name: Yokai. Yokai is the name of that reusable generic CMake framework. CMake variables are prefixed with YOKAI_, C definitions are prefixed with YOKAI_ as well, and folders for generated files are 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).

@illwieckz
Copy link
Copy Markdown
Member Author

One commit renames the framework to Yokai and but keeps a variable substitution mechanism to not break the existing DAEMON_ prefixed things in C/C++ code and CMake code outside of Yokai, then the next commit removes the substitutions and fully embraces the Yokai namespace in the C/C++ and CMake code all the way down.

@illwieckz illwieckz force-pushed the illwieckz/cmake-platform branch from 43f13f8 to ad6906a Compare June 4, 2026 17:24
@slipher
Copy link
Copy Markdown
Member

slipher commented Jun 5, 2026

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.

Please no. The built-in WIN32 works fine. It is obnoxious to replace a standard language feature with a custom implementation. Anyone who was worked with CMake in other projects will not be able to use their knowledge. Anyone working on the project, familiar with CMake or not, will be inconvenienced by the use of a homemade version which does not appear in search engines, forcing them to read a bunch of crap to figure out what it is.

# Daemon BSD Source Code
# Copyright (c) 2025, Daemon Developers
# YOKAI BSD Source Code
# Copyright (c) 2025, YOKAI Developers
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.

It's annoying to proliferate different author names because then we would have to update the author lists whenever moving things between files.

Comment thread srclibs.cmake
${LIB_DIR}/breakpad/src/client/windows/handler/exception_handler.h
)
elseif (LINUX)
elseif (YOKAI_SYSTEM_Linux_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.

Does Breakpad Linux code seriously work on some non-Linux OS? Would be surprising since debugger APIs are very OS-specific. But if you want to try it I have a testing script: #1785

Comment thread CMakeLists.txt
# Look for OpenGL here before we potentially switch to looking for static libs.
if (BUILD_CLIENT)
if (LINUX OR FREEBSD)
if (YOKAI_SYSTEM_Unix_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.

I assume "Unix compatibility" would include Mac? Then this is wrong because this GLVND stuff should not be set on Mac.

Comment thread cmake/DaemonFlags.cmake
# Target options.
if (MSVC)
if (ARCH STREQUAL "i686")
if (YOKAI_CXX_COMPILER_MSVC)
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.

Replacing MSVC conditionals with this breaks the clang-cl compiler which is both Clang and MSVC. It is correctly detected by CMake:

-- The C compiler identification is Clang 19.1.5 with MSVC-like command-line
-- The CXX compiler identification is Clang 19.1.5 with MSVC-like command-line

clang-cl works on master but this PR breaks it by feeding it GCC-specific options.

Was there anything wrong with CMake's compiler detection that you saw?

@slipher
Copy link
Copy Markdown
Member

slipher commented Jun 5, 2026

Besides clang-cl being broken, regular old MSVC also doesn't work.

NaCl VM is not supported on this platform. Set vm.cgame.type and vm.sgame.type to 3 (native DLL) and use devmap instead of map.

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