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

SDL:不应该在启用 sdlmain 配置时定义 SDL_MAIN_HANDLED 宏。 #2997

Closed
63enjoy opened this issue Dec 27, 2023 · 2 comments
Closed
Labels

Comments

@63enjoy
Copy link
Contributor

63enjoy commented Dec 27, 2023

Xmake 版本

2.8.6

操作系统版本和架构

Windows 11 23H2 22631.2861

描述问题

通过 xrepo 引用 SDL 库,如果启用了 sdlmain 配置,会自动定义 SDL_MAIN_HANDLED 宏。

on_component("main", function (package, component)
local libsuffix = package:is_debug() and "d" or ""
component:add("links", "SDL2main" .. libsuffix)
component:add("defines", "SDL_MAIN_HANDLED")
component:add("deps", "lib")
end)

SDL 中默认会将 main 宏定义为 SDL_main,然后 SDL 会定义自己的入口点函数,在其中调用 SDL_main 函数。
SDL_MAIN_HANDLED 宏的实际作用是不将 main 宏定义为 SDL_main,也就是在不使用 sdlmain 而使用自定义 main 函数(如 WinMain)时才需要定义这个宏。
在使用 sdlmain 的情况下定义 SDL_MAIN_HANDLED 宏,会导致找不到 SDL_main 函数的定义。

期待的结果

应在启用了 sdlmain 配置时不定义 SDL_MAIN_HANDLED 宏,在不启用 sdlmain 配置时定义 SDL_MAIN_HANDLED 宏。

工程配置

  • xmake.lua
    add_rules("mode.debug", "mode.release")
    
    add_requires("libsdl")
    
    target("SDLDemo")
        add_files("src/main.cpp")
        add_packages("libsdl")
        add_ldflags("-subsystem:windows")
  • src/main.cpp
    // #undef SDL_MAIN_HANDLED // 取消定义 SDL_MAIN_HANDLED 宏后才可正常编译
    #include <SDL.h>
    
    int main(int argc, char *argv[])
    {
        SDL_Init(SDL_INIT_EVERYTHING);
        SDL_Window *window = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
        bool quit = false;
        SDL_Event event;
        while (!quit)
        {
            while (SDL_PollEvent(&event))
            {
                switch (event.type)
                {
                case SDL_QUIT:
                    quit = true;
                    break;
                }
            }
        }
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 0;
    }

附加信息和错误日志

  • 链接错误:
    [ 50%]: linking.release SDLDemo.exe
    error: SDL2main.lib(SDL_windows_main.obj) : error LNK2005: main 已经在 main.cpp.obj 中定义
    SDL2main.lib(SDL_windows_main.obj) : error LNK2019: 无法解析的外部符号 SDL_main,函数 main_getcmdline 中引用了该符号
    build\windows\x64\release\SDLDemo.exe : fatal error LNK1120: 1 个无法解析的外部命令 
    
  • 附加信息:
    此问题似乎是在 fix sdl main #732 中引入的。
@63enjoy 63enjoy added the bug label Dec 27, 2023
@waruqi waruqi mentioned this issue Dec 27, 2023
@waruqi
Copy link
Member

waruqi commented Dec 27, 2023

#2999

@vkensou
Copy link
Contributor

vkensou commented Sep 24, 2024

记录一下
如果在windows下要使用sdlmain,一定要设置subsystem
下面这样的写法可以通过编译:

add_rules("mode.debug", "mode.release")

add_requires("libsdl", {configs = {sdlmain = true}})

target("SDLDemo")
    add_files("main.cpp")
    add_packages("libsdl")
    add_ldflags("-subsystem:windows")
    -- add_ldflags("-subsystem:console")
#include <SDL.h>

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Window *window = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
    bool quit = false;
    SDL_Event event;
    while (!quit)
    {
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_QUIT:
                quit = true;
                break;
            }
        }
    }
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants