Closed icculus closed 1 year ago
Windows is the only platform where you could conceivably do this. Windows RT / Xbox, iOS, PSP, etc. all require you to have a separate file with the main implementation. iOS actually requires you to have the main implementation in an Objective C file included with your application - you can't use a static library at all.
What you're proposing is essentially including SDL_windows_main.c in a header that you include, but only on Windows. At that point you might as well include SDL_windows_main.c as a source file in your project. That file was put in the public domain in 1998 for just that purpose.
I completely agree with your reasoning, and agree with the benefits, but I don't see an elegant way to do that and still support other platforms.
@DanielGibson, feel free to submit a PR which solves this.
Windows RT / Xbox, iOS, PSP, etc. all require you to have a separate file with the main implementation
That sucks, and the only of these platforms I can even develop for and test on is Win RT.
I'll look into it anyway.
A middle ground might be to provide an empty dummy libSDL3main on platforms that can use a header-only solution, and a real libSDL3main only for those that need it (because it needs to be implemented in obj-c or c++ or whatever) and use the header-only solution?
Then building SDL3 apps could work the same everywhere: You #include <SDL3/SDL_main.h>
in your source file that implements main()
and link against libSDL3main
(even though that's a no-op on most platforms) - though in case you have to handle different operating systems differently in your build system anyway (or don't care about the platforms that need it as a lib), you can also skip the linking part of course.
(Admittedly, this is pretty much the same as it works now, with the difference that we get the header-only benefits on Windows and similar platforms that need the SDL_main functionality and allow implementing it in C)
Regarding:
Windows RT / Xbox, iOS, PSP, etc. all require you to have a separate file with the main implementation
Why iOS and PSP? They both seem to implement their SDL main stuff in plain C, so it could be in a header-only lib - or am I missing anything?
Of course it seems to be different for Haiku, ngage and WinRT, those three use C++ (though I wonder if any of those platforms would support putting the SDL_main C++ code into the dynamic libSDL and call that from a possibly-C-header-only SDLmain)
Ah, you're right, I was thinking that iOS was Objective C.
iOS is particularly painful in that you have to have the code in your application, you can't link to a library to pick up the main entry point.
I'm willing to entertain a new approach in SDL3, as long as it works well across the different platforms.
Some remarks and questions about the C++ platforms:
If I understand https://github.com/libsdl-org/SDL/blob/main/docs/README-winrt.md correctly, there is no static SDLmain lib for WinRT, instead apps need to add SDL_winrt_main_NonXAML.cpp
to their build and compile it as part of their app, because
WinRT uses a different signature for each app's main() function. SDL-based apps that use this port must compile in SDL_winrt_main_NonXAML.cpp (in SDL\src\main\winrt) directly in order for their C-style main() functions to be called.
I think this means that moving that code into a header-only SDL_main_winrt.hpp that must be #included from a .cpp file of the project would make usage slightly easier (no need to copy a source file from the SDL sourcetree)? (And if for some reason that's a bad idea, we can still ignore WinRT for SDL_main considerations because there is no libSDLmain for WinRT to link against either way)
Disclaimer: Haiku isn't documented in docs/ and I have no experience with Haiku/BeOS development at all so I can only make deductions from the source code
As far as I see it, there is no main()-like function in src/main/haiku/
.
Apparently the way it works is that you have a "normal" main() function and code, and when you call SDL_Init()
and then through SDL_VideoInit()
HAIKU_VideoInit()
(from src/video/haiku/SDL_bvideo.cc
) is called which calls SDL_InitBeApp()
(a similar path exists via SDL_InitAudio()
). And then there's the counter-part, HAIKU_VideoQuit()
calling SDL_QuitBeApp()
.
Anyway, SDL_InitBeApp()
and SDL_QuitBeApp()
are implemented in SDL_main.
So question for people who know about Haiku: Is that really necessary?
As apparently everything that happens at startup, including linking/loading libSDL, main()
and calling SDL_Init()
works without the code in SDL_main, does that code really have to be in a separate, static library? Couldn't SDL_InitBeApp()
and SDL_QuitBeApp()
(and the class SDL_BApp
that's created/destroyed by those functions) also be implemented in the dynamic libSDL3 itself?
Another platform I know nothing about :)
I see extern "C" int main(int argc, char *argv[]);
(which then is not referenced/used again - does it have a specific purpose?)
and TInt E32Main()
which seems to contain relevant code and eventually calls SDL_main
and uses C++-constructs.
So, question for people who know about ngage development: Couldn't we move the code from E32Main()
into int SDL_E32MainImpl()
in libSDL itself, and let the SDLmain
part be pure C code that just calls that?
(Maybe int SDL_E32MainImpl(SDL_main_func mainfunc)
to pass the users main function as a function pointer that's called there)
Bonus-question (as this doesn't use C++): src/main/android/SDL_android_main.c is an empty file with a As of SDL 2.0.6 this file is no longer necessary.
comment - maybe it should just be removed?
One more thing: SDL_main.h currently serves multiple purposes:
SDL_MAIN_NEEDED
and SDL_MAIN_AVAILABLE
- also used by SDLs implementation code#define main SDL_main
so the libSDLmain code can call SDL_main() instead of main()SDL_RegisterApp()
and SDL_WinRTRunApp()
, SDL_UIKitRunApp()
etc that users may wanna call in their own main() codeSo when turning SDL_main.h into a header-only lib that (on platforms that use some kind of SDL_main functionality, basically SDL_MAIN_AVAILABLE
I guess) implements the main() magic that in SDL2 lives in libSDLmain, we have (at least) two options how to handle this:
SDL_MAIN_NEEDED
and SDL_MAIN_AVAILABLE
and declaring platform-specific main-related functions, if any. For example SDL_main_impl.h
(for the header-only lib with the implementation and the main-#define) and SDL_main.h
for the rest#ifndef SDL_MAIN_HANDLED
around the implementation partsI started implementing this, so far only for ("classic") Windows. You can see the WIP at https://github.com/libsdl-org/SDL/pull/6750
Now that #6750 is merged, this can probably be closed :)
@madebr: As you seem to be very involved with SDLs CMake build, do you think it would now be feasible to do some magic in SDL3Config.cmake (or whatever is shipped with SDL3 builds) to make it possible to use MinGW builds with MSVC?
As I wrote above:
For the SDL2.lib only used for linking the DLL it's not that bad, because it can relatively easily be generated from SDL2.dll (create a .def with mingw's gendef SDL2.dll and then use lib.exe /machine:x86 /def:SDL2.def /out:SDL2.lib in the VS developer console to generate the lib) - but that doesn't help for SDL2main.lib, which is a proper static lib and not just this stub-thing used on Windows to link DLLs.
As the SDLmain part of the problem is now solved, it should be possible to ship SDL3.def with the cmake scripts, and when they're used with MSVC (and the SDL3.dll was built with MinGW), the required SDL3.lib could be created from SDL3.def with the lib.exe of the users machine
Just a wild idea ;)
That's correct for SDLx.dll, but the MSVC and MinGW sdk's also ship static libraries.
The SDL2 MinGW sdk also contain libSDL2.a
and libSDL2_test.a
.
The SDL2 VC sdk also contains SDL2test.lib
.
The static SDLx libraries depends on the c library it is compiled with. So I am not 100% sure this will work for these.
Last time I tried, I was able to use the VC sdk with a MinGW toolchain (using a shared SDL). So I think generating an import library is not needed in this case. I haven't tested the reverse case (a MinGW SDK with a VC toolchain).
Using an SDL SDK built with MSVC with MinGW works (MinGW can use the .lib), but the other way around doesn't work because MSVC can't use libSDL2.dll.a or however it's called (not the full static lib but the equivalent of the glue .lib for DLLs). And even though MinGW can generate .lib files, those are incompatible with modern versions of MSVC ("module unsafe for SAFESEH").
Yeah, full static libs built with MinGW still wouldn't work with MSVC, but having the dynamic lib work might be nice to have (people aren't supposed to link SDL statically anyway :-p)
Yeah, full static libs built with MinGW still wouldn't work with MSVC, but having the dynamic lib work might be nice to have (people aren't supposed to link SDL statically anyway :-p)
Speaking of which, @madebr, can we default SDL static off in CMake?
Speaking of which, @madebr, can we default SDL static off in CMake?
Sure, I will include it in the next cmake pr.
Using an SDL SDK built with MSVC with MinGW works (MinGW can use the .lib), but the other way around doesn't work because MSVC can't use libSDL2.dll.a or however it's called (not the full static lib but the equivalent of the glue .lib for DLLs). And even though MinGW can generate .lib files, those are incompatible with modern versions of MSVC ("module unsafe for SAFESEH").
I don't see a SAFESEH
warning when linking against a libSDL3.dll.a
, created by a mingw64 toolchain from msys2 (Using gcc 11.2.0 and cl 19.29.30147 (=MSVC2019))
Perhaps current toolchains have fixed this?
I created this branch on my sdl2 fork that will recreate a sdl2 import library, but I don't see any benefits and don't really like it.
I think that warning happened with older import libraries. For a retro project, I link to ancient directx7 sdk import libraries (downloaded from archive.org) where I remember seeing similar warnings.
Speaking of which, @madebr, can we default SDL static off in CMake?
You can currently do that by configuring with -DBUILD_SHARED_LIBS=ON
.
This has been implemented, thanks!
Originally posted by @DanielGibson in https://github.com/libsdl-org/SDL/issues/3519#issuecomment-1014960548