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

Allow to have both WinMain and main defined on Windows #1167

Merged
merged 3 commits into from
Dec 14, 2024

Conversation

Querijn
Copy link
Contributor

@Querijn Querijn commented Dec 11, 2024

My library uses Sokol under the hood and requires you to define

add_executable(example WIN32 main.cpp)
target_link_libraries(example MyLib) # MyLib uses Sokol

when on Windows by default. If you were to use add_executable(example main.cpp) instead, it would not link due to the missing main entrypoint. I could define SOKOL_WIN32_FORCE_MAIN for MyLib to force main(), but then I could not create a WinMain unless I removed it again. I considered doing NO_ENTRY and defining both locally in the library but that seemed like more work (and less in the spirit of open-source) than making a PR.

This PR addresses this problem, creating a definition for SOKOL_WIN32_FORCE_WINMAIN. This allows you to force either or both, where the default behaviour is the original behaviour.

  • Defining neither is effectively the same as defining SOKOL_WIN32_FORCE_WINMAIN, which creates a WinMain entry point.
  • Defining only SOKOL_WIN32_FORCE_MAIN will create just the main entry point, and not the WinMain entry point.
  • Defining both will create both.

I'm not happy about the length of the extra line I added in the documentation, and I'm open to modify it if you have a better idea.

@floooh
Copy link
Owner

floooh commented Dec 11, 2024

I wonder if it works to just remove all the FORCE defines and just always have both main() and WinMain() in the code (unless SOKOL_NO_ENTRY is defined which would remove both main() and WinMain()). Did you try that already? I'll need to tinker with this idea a bit, if it works I would prefer that since it removes a bit of configuration complexity.

@Querijn
Copy link
Contributor Author

Querijn commented Dec 11, 2024

I did! That is what I did before I decided to make this PR. It worked fine on my machines, Windows 10/Windows 11 were tested at the time.

Only concern I can think is that maybe existing systems depend on the existence of either, not both and are therefore configured on that. Defining both would break this very hypothetical case.

Oh, and the subsystem has to be explicitly defined:

sokol/sokol_app.h

Lines 2188 to 2194 in a94f66a

#if !defined(SOKOL_NO_ENTRY) // if SOKOL_NO_ENTRY is defined, it's the applications' responsibility to use the right subsystem
#if defined(SOKOL_WIN32_FORCE_MAIN)
#pragma comment (linker, "/subsystem:console")
#else
#pragma comment (linker, "/subsystem:windows")
#endif
#endif

@floooh
Copy link
Owner

floooh commented Dec 11, 2024

Oh, and the subsystem has to be explicitly defined...

...does the pragma-comment magic at that place actually work with your PR when both SOKOL_WIN32_FORCE_WINMAIN and SOKOL_WIN32_FORCE_MAIN are defined? E.g. I guess you need to override that in your build script's linker setting to pick one or the other?

This is actually a situation where the pragma-comment-magic in sokol_app.h is becoming confusing (even though it's very convenient for 'regular situations').

I also just saw that there's this outdated thingie (outdated because UWP / WinRT is no longer supported):

sokol/sokol_app.h

Lines 2002 to 2008 in a94f66a

// this WinRT specific hack is required when wWinMain is in a static library
#if defined(_MSC_VER) && defined(UNICODE)
#include <winapifamily.h>
#if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#pragma comment(linker, "/include:wWinMain")
#endif
#endif

PS: maybe it makes sense to not set any subsystem at all via pragma-comment when both SOKOL_WIN32_FORCE_MAIN and SOKOL_WIN32_FORCE_WINMAIN is defined?

@Querijn
Copy link
Contributor Author

Querijn commented Dec 11, 2024

Oh, and the subsystem has to be explicitly defined...

...does the pragma-comment magic at that place actually work with your PR when both SOKOL_WIN32_FORCE_WINMAIN and SOKOL_WIN32_FORCE_MAIN are defined? E.g. I guess you need to override that in your build script's linker setting to pick one or the other?

CMake + the Visual Studio generator solves this correctly somehow, I did not need any changes to this and the correct subsystem was used..

PS: maybe it makes sense to not set any subsystem at all via pragma-comment when both SOKOL_WIN32_FORCE_MAIN and SOKOL_WIN32_FORCE_WINMAIN is defined?

Maybe removing the force altogether is the better call, but yeah, that makes sense.

@Querijn
Copy link
Contributor Author

Querijn commented Dec 11, 2024

I've checked again, enabling both will open up a console window even when starting through WinMain. Which might be undesired behaviour. So I'm convinced removing these is a better call.

@floooh
Copy link
Owner

floooh commented Dec 11, 2024

Yeah, my current thinking is: keep the idea to have both FORCE defines (e.g. what your PR does), but change this block so that no subsystem is set when both are defined:

     #if defined(SOKOL_WIN32_FORCE_MAIN) 
         #pragma comment (linker, "/subsystem:console") 
     #else 
         #pragma comment (linker, "/subsystem:windows") 
     #endif

Can you update the PR for that?

Also, while you're at it, can you remove this leftover UWP snippet? Thx :)

sokol/sokol_app.h

Lines 2002 to 2008 in a94f66a

// this WinRT specific hack is required when wWinMain is in a static library
#if defined(_MSC_VER) && defined(UNICODE)
#include <winapifamily.h>
#if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#pragma comment(linker, "/include:wWinMain")
#endif
#endif

@Querijn
Copy link
Contributor Author

Querijn commented Dec 11, 2024

This should be it. Would you like me to squash it or is this OK?

@floooh
Copy link
Owner

floooh commented Dec 12, 2024

Looks good now. I'll play around with it a bit though, will most likely merge on Saturday.

@floooh floooh merged commit f9218f2 into floooh:master Dec 14, 2024
32 checks passed
@floooh
Copy link
Owner

floooh commented Dec 14, 2024

Ok merged, thanks! I'll also write a little changelog entry.

floooh added a commit that referenced this pull request Dec 14, 2024
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