SDL2 main 未调用且无输出,链接问题?

问题描述 投票:0回答:1

问题

使用 CMake 作为 makefile 生成器构建 SDL2 应用程序时,构建的应用程序在打开后立即关闭,没有输出,即使使用 SDL_sleep(int) 也是如此。平台等是 64 位的,尽管以后最好也支持 32 位。

我试过的

  • 在删除 SDL_MAIN_HANDLED 和 SDL_SetMainReady() 的同时使用 SDL_main(无变化)
  • 使用 find_package(找不到 + 由于驱动器大小限制,我想将 SDL2 保留在包含目录中 + 希望将所有项目数据和包含在一个地方,SDL2 不用于其他项目)
  • plain hello world(构建和工作。仅当添加 SDL2 时,项目停止完全输出任何数据,甚至停止使用 SDL_sleep(int))
  • 搜索信息,但似乎大多数人都从 SDL_SetMainReady 中找到了帮助,使用 int main(int argc, char** argv) 和 SDL_MAIN_HANDLED,这对我的情况没有帮助。此外,由于我使用的 SDL2 位于 ./includes/ find_package 中,因此对我不起作用。
  • 删除整个 ./build/ 目录(CMakeCache 所在的位置),但它并没有改变结果。

构建和运行时的控制台输出

PS F:\Koodit\Vivaria> .\scripts\build_windows_debug_x64.bat 

F:\Koodit\Vivaria>mkdir build

F:\Koodit\Vivaria>cmake -G "MinGW Makefiles" -S . -B ./build/ -DCMAKE_TOOLCHAIN_FILE=./buildtools/win-x64-debug.cmake ..
-- The C compiler identification is GNU 10.1.0
-- The CXX compiler identification is GNU 10.1.0
-- Check for working C compiler: C:/msys64/mingw64/bin/gcc.exe
-- Check for working C compiler: C:/msys64/mingw64/bin/gcc.exe - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/x86_64-w64-mingw32-g++.exe
-- Check for working CXX compiler: C:/msys64/mingw64/bin/x86_64-w64-mingw32-g++.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: F:/Koodit/Vivaria/build


F:\Koodit\Vivaria\build>mingw32-make
mingw32-make[1]: Entering directory 'F:/Koodit/Vivaria/build'
mingw32-make[2]: Entering directory 'F:/Koodit/Vivaria/build'
Scanning dependencies of target Vivaria
mingw32-make[2]: Leaving directory 'F:/Koodit/Vivaria/build'
mingw32-make[2]: Entering directory 'F:/Koodit/Vivaria/build'
[ 50%] Building CXX object CMakeFiles/Vivaria.dir/src/vivaria.cpp.obj
[100%] Linking CXX executable ..\deploy\Windows_x64_Debug\Vivaria.exe
mingw32-make[2]: Leaving directory 'F:/Koodit/Vivaria/build'
[100%] Built target Vivaria
mingw32-make[1]: Leaving directory 'F:/Koodit/Vivaria/build'
PS F:\Koodit\Vivaria> .\deploy\Windows_x64_Debug\Vivaria.exe
PS F:\Koodit\Vivaria>

设置

应用

  • Windows 10, 64bit(+应该是跨平台的,不仅仅是windows)
  • SDL2 2.0.12
  • CMake 3.17
  • 管理系统
  • Mingw64
  • IDE:Visual Studio Code(不是 Visual Studio!)

包含的文件(当前为 SDL2)使用 install_buildtools_xxx.xxx 脚本安装到包含目录。那(应该)允许在不同的计算机上快速设置项目。

项目结构

文件结构

├── build
│   └── -cmake generated files
├── buildtools
│   └── win-x64-debug.cmake
├── deploy
│   └── Windows_x64_Debug
│       └── Vivaria.exe
├── includes
│   └── SDL2
│       └── SDL2-2.0.12
│           └── lib
│               └── x64
│                   ├── SDL2.lib
│                   └── SDL2main.lib
├── resources
├── scripts
│   ├── install_includes_windows.bat
│   ├── build_windows_debug_x64.bat
│   └── build_windows_debug_x86.bat
├── src
│   ├── vivaria.h
│   └── vivaria.cpp
└── CMakeLists.txt

重要文件

vivaria.h

#ifndef VIVARIA_H
#define VIVARIA_H

#include "SDL.h"

class Vivaria {
    private:
        bool running;
        SDL_Window* window;
    public:
        Vivaria();
        int onExecute();

        bool onInit();
        void onEvent(SDL_Event* event);
        void onLoop();
        void onRender();
        void onCleanup();
        SDL_Window* getWindow() const;
};

#endif

vivaria.cpp(重要的部分)

#define SDL_MAIN_HANDLED
#include <iostream>
#include "SDL.h"
#include "vivaria.h"

int main(int argc, char* argv[]) {
    SDL_SetMainReady();
    Vivaria game;
    return game.onExecute();
}

Vivaria::Vivaria() {
    std::cout << "Starting Vivaria..." << std::endl;
}

// called in onExecute
bool Vivaria::onInit() {
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
        return false;
    }

    window = SDL_CreateWindow(
        "Vivaria",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        640,
        480,
        SDL_WindowFlags::SDL_WINDOW_OPENGL
    );

    if(window == nullptr) {
        printf("Could not create window: %s\n", SDL_GetError());
        return false;
    }
    return true;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.17)
project(Vivaria VERSION 1.0.0)

set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/includes")
set(SDL2_DIR "${INCLUDE_DIR}/SDL2/SDL2-2.0.12")

set(SDL2_INCLUDE_DIRS "${SDL2_DIR}/include")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/deploy/${CMAKE_SYSTEM_NAME}_${BITSIZE}_${CMAKE_BUILD_TYPE}/")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/deploy/${CMAKE_SYSTEM_NAME}_${BITSIZE}_${CMAKE_BUILD_TYPE}/lib")
set(SDL2_MAIN_LIB "${SDL2_DIR}/lib/${BITSIZE}/SDL2main.lib")
set(SDL2_LIB "${SDL2_DIR}/lib/${BITSIZE}/SDL2.lib")

link_directories(${SDL2_LIBRARIES})

# Project files and linking
set(SOURCES
src/vivaria.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})

target_include_directories(${PROJECT_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${SDL2_MAIN_LIB} ${SDL2_LIB})

win-x64-debug.cmake

set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++.exe)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_MAKE_PROGRAM mingw32-make.exe)

# flags
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)

set(BITSIZE x64)

build_windows_debug_x64.bat

mkdir build

cmake -G "MinGW Makefiles" -S . -B ./build/ -DCMAKE_TOOLCHAIN_FILE=./buildtools/win-x64-debug.cmake ..

cd .\build\
mingw32-make
c++ cmake sdl-2
1个回答
0
投票

我在 2023 年 3 月遇到了同样的问题,虽然这个帖子早已关闭,但我遇到了同样的问题并且花了太多时间寻找解决方案。这是今天在 Windows 上有效的东西。

设置

  • Windows 10
  • 64位
  • SDL2
  • 自制
  • 编译器 MSVC 2019 (19.26.28806.0)
  • VS代码

解决步骤:

工作 CMAKE 文件

cmake_minimum_required(VERSION 3.0)

project(SDL2Test)

#   Windows
IF (WIN32)
    list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/ext/win_sdl2_2.26.4/cmake)
ENDIF(WIN32)

find_package(SDL2 REQUIRED)

include_directories(${SDL2_INCLUDE_DIRS})

message("SDL2_INCLUDE_DIRS: ${SDL2_INCLUDE_DIRS}")
message("SDL2_INCLUDE_DIRS: ${SDL2_LIBRARIES}")

add_executable(SDL2Test Main.cpp)

#   Will also like to SDL2Main.lib and defining SDL_MAIN_HANDLED has NO EFFECT
#target_link_libraries(SDL2Test ${SDL2_LIBRARIES})

#   Link just the SDL2.lib and not SDL2main.lib
#   This allows defining SDL_MAIN_HANDLED to take effect and call int main(int argc, char* argv[])
target_link_libraries(SDL2Test ${CMAKE_CURRENT_SOURCE_DIR}/ext/win_sdl2_2.26.4/lib/x64/SDL2.lib)

工作测试文件*

#define SDL_MAIN_HANDLED
#include "SDL.h"

//  If you define SDL_MAIN_HANDLED and do not link to SDL2main.lib
int main(int argc, char* argv[]) {

  SDL_Init(SDL_INIT_VIDEO);

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    0
  );

  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
  SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderClear(renderer);
  SDL_RenderPresent(renderer);

  SDL_Delay(3000);

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;

}

//  Called if you don't define SDL_MAIN_HANDLED, whether you link to SDL2main.lib or not
int wmain(void) {
  SDL_Init(SDL_INIT_VIDEO);

  SDL_Window *window = SDL_CreateWindow(
    "SDL2Test",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    0
  );

  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
  SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
  SDL_RenderClear(renderer);
  SDL_RenderPresent(renderer);

  SDL_Delay(3000);

  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.