Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a way to add a 100% external custom platform / CMake #3596

Closed
wants to merge 1 commit into from
Closed

Introduce a way to add a 100% external custom platform / CMake #3596

wants to merge 1 commit into from

Conversation

ypujante
Copy link

@ypujante ypujante commented Dec 2, 2023

Let me start with a few things (in order to avoid misunderstanding):

  • this is based on this discussion/comment
  • I closed another PR because I was told it was not the right way to go about it
  • if you want to close and forget all about it I am perfectly fine with it

The purpose of this PR is to implement a way for raylib to support platforms that are NOT embedded in raylib and as a result not maintained by @raysan5.

Goals (that I believe I have achieved with this PR)

  • developing a new (external) platform should require 0 changes to raylib (the raylib repo)
  • it should be fairly simple for a platform developer to write an external platform (the actual code in the platform itself might be complicated, but that is besides the point...)
  • it should be fairly simple for a user to use a platform that is not embedded in raylib
  • changing raylib to support external/custom platforms should not affect the build/runtime/compile time performance of the embedded platforms
  • there are no changes to current platforms

After looking at the source code, I believe there are 2 areas where there needs to be "hooks" for a platform to reside outside raylib:

  • the source code: actual implementation of the platform + various defines to tailor the build
  • the build files: which libraries to include, link options, compile options, etc... Note that for this PR I concentrated only on CMake because I do not know about Makefiles/zig. These other build frameworks could be added later (via other PR).

The overall approach that I took is the following: use conventions as much as possible so that it is easy both from the user of the platform and the developer of the platform to integrate with raylib.

The "only" required pieces of information that raylib needs are:

  • the fact that is a custom platform (added a new enum options "Custom")
  • where the platform is located on the file system. In CMake this translates into providing a PLATFORM_CUSTOM_ROOT_DIR variable.

The custom platform looks like this (by convention):

root/cmake
       raylibPlatformCustomLibraryConfig.cmake [optional]
       raylibPlatformCustomTargetConfig.cmake  [optional]
       raylibPlatformCustomProjectConfig.cmake [optional]
root/src
       raylib_platform_custom.c [required]
       raylib_platform_custom.h [required]
  • cmake/raylibPlatformCustomProjectConfig.cmake: optional and contain cmake definitions that needs to happen before project() is invoked
  • cmake/raylibPlatformCustomLibraryConfig.cmake: optional and contain cmake definitions of libraries and generic option (like setting CMAKE_STATIC_LIBRARY_SUFFIX)
  • cmake/raylibPlatformCustomTargetConfig.cmake: optional and contain cmake definitions that applies on the raylib target (ex: target_link_options(raylib PRIVATE "-sUSE_GLFW=3"))
  • src/raylib_platform_custom.c is the implementation of the platform that gets included in rcore.c (similar to platforms/rcore_desktop.c)
  • src/raylib_platform_custom.h is a new header file containing several definitions that are used in the code

Let me give an example of the last one: in rlgl.h there is this code:

    #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)

so I changed it to

    #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) || defined(PLATFORM_CUSTOM_ENABLE_OPENGL_ES2)

and PLATFORM_CUSTOM_ENABLE_OPENGL_ES2 is a define that needs to be defined (or not) in the src/raylib_platform_custom.h

The name PLATFORM_CUSTOM_ENABLE_OPENGL_ES2 as well as the other entries in this file have been inferred by what the #if is supposed to mean but not knowing the code, that was my best bet.

I understand this is a lot (to explain, but in the end not a lot of changes!)

I have another branch that you can checkout/clone which demonstrates 2 custom platforms and 2 examples of how to use them under the external folder.

As you will see the 2 custom platforms are simply clones of 2 built-in ones, but they get used as a custom/external platform, NOT a built-in one.

The PR in its current state, is fully functional. But obviously I am open to feedback and proposed changes, especially when it comes to naming and conventions. As stated previously, it works with CMake only.

removed unecessary section

removed external
@ColleagueRiley
Copy link
Contributor

I believe the example files should be main.c and not main.cpp, I'm pretty sure they're already written in C anyway.

@raysan5
Copy link
Owner

raysan5 commented Dec 3, 2023

@ypujante Thanks for all the work put on this improvement but in my experience the complexity to support additional platforms could require additional changes not considered by those changes and consequently I'd avoid a solution trying to simplify the process that could actually complicate the process. Two real use-case examples:

  • raylib4PlayStation: Two new platforms supported, PS4 and PSVita homebrew, updated for raylib 5.0 some days ago. The implementation is provided as a patch for raylib, adding two new rcore_<platform>.c files (rcore_orbis.c, rcore_vita.c). The implementation is greatly simplified in comparison to previous raylib versions but still it requires customizations over several raylib modules, most notably rlgl for proper shaders support. The build system also requires lot of customization to link with proper libraries.
  • rcore_switch.cpp: I implemented Nintendo Switch support to test the new platform-split and again, it despite being quite easy in terms of implementation (i.e no changes required in rlgl module), the build system required was completely different to anything available in raylib; rcore_switch.cpp is required to be compiled as an external library and linked together with the rest of raylib referencing external symbols.
  • I took a quick look to Xbox Series X|S support (through GLon12) and similar issues arise.

So, despite the efforts to simplify the addition of external custom platforms, I think it's easier to leave it up to the users requiring it, through a fork and all required build customization, and avoid getting in the middle trying to provide a mechanism that could not fit.

Also, on that line, I think raylib source code is simple enough that most advance users will feel more confortable just having full control over it and do not need a predefined plugin mechanism.

For those reasons, I'm afraid I prefer to avoid this implementation.

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.

3 participants