将 SDL2 与 CMake 链接起来
Linking SDL2 with CMake
我在将 SDL2 链接到我的项目时遇到问题,这可能是因为我是 CMake 的新手,我不完全知道如何使用它创建新项目。每次我尝试解决此问题的方法都会导致以下问题之一:
- "找不到WinMain@16">
- 多个未定义的参考错误
- 对"SDL_main"的未定义引用
我尝试使用find_package,直接链接到文件,链接到库文件,遵循教程(例如 https://trenki2.github.io/blog/2017/06/02/using-sdl2-with-cmake/(,搜索答案(其中大多数都谈到使用我无法工作的find_package((例如将SDL2与CMake一起使用(。
项目依赖关系
SDL 2.0.12,CMake 3.17.0, 7-Zip, mingw32-make, wget
该项目应该是跨平台的,但主要的开发点是Windows 10。所有脚本都从根文件夹"vivaria"运行。
项目结构
vivaria/
├── build/
│ └── [cmake build files]
├── buildtools/
│ └── SDL2/SDL2-2.0.12/lib/x86 (and x64)
│ ├── SDL2.lib
│ └── SDL2main.libs
├── deploy/
├── resources/
├── scripts/
│ ├── build_windows_debug_x86.bat
│ └── install_buildtools_windows.bat
└── src/
├── CMakeLists.txt
└── vivaria.cpp
build_windows_debug_x86.bat
cmake -G "MinGW Makefiles" -S .src -B .build -DCMAKE_BUILD_TYPE=Debug
cd .build
mingw32-make
维瓦里亚.cpp
#include <iostream>
#include "SDL.h"
int main() {
if (SDL_Init(SDL_INIT_VIDEO) != 0){
std::cout << "Hello world" << std::endl;
return 1;
}
SDL_Quit();
return 0;
}
CMakeLists.txt:未定义的SDL_main引用
cmake_minimum_required(VERSION 3.17)
project(Vivaria VERSION 1.0.0)
set(CMAKE_CXX_GLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lmingw32")
# set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/../buildtools")
set(SDL2_DIR "${INCLUDE_DIR}/SDL2/SDL2-2.0.12")
set(SDL2_INCLUDE_DIRS "${SDL2_DIR}/include")
set(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/../deploy")
# Support both 32 and 64 bit builds
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
set(SDL2_LIBRARIES "${SDL2_DIR}/lib/x64/SDL2main.lib;${SDL2_DIR}/lib/x64/SDL2.lib")
else ()
set(SDL2_LIBRARIES "${SDL2_DIR}/lib/x86/SDL2main.lib;${SDL2_DIR}/lib/x86/SDL2.lib")
endif ()
# link dependencies
include_directories(${SDL2_INCLUDE_DIRS})
link_directories(${SDL2_LIBRARIES})
# Project files and linking
set(SOURCES vivaria.cpp)
add_executable(${PROJECT_NAME} vivaria.cpp)
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})
控制台输出
F:KooditVivariabuild>mingw32-make
[ 50%] Linking CXX executable Vivaria.exe
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: F:/Koodit/Vivaria/src/../buildtools/SDL2/SDL2-2.0.12/lib/x86/SDL2main.lib(Win32/Release/SDL_windows_main.obj):(.text[_main_getcmdline]+0xd1): undefined reference to `SDL_main'
collect2.exe: error: ld returned 1 exit status
CMakeFilesVivaria.dirbuild.make:104: recipe for target 'Vivaria.exe' failed
mingw32-make[2]: *** [Vivaria.exe] Error 1
CMakeFilesMakefile2:91: recipe for target 'CMakeFiles/Vivaria.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/Vivaria.dir/all] Error 2
Makefile:99: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
install_buildtools_windows.bat
set SDL2=SDL2-devel-2.0.12-VC.zip
set DOWNLOAD_DIR=%cd%buildtools
set OUTPUT_DIR=%cd%buildtoolsSDL2
wget "https://libsdl.org/release/%SDL2%" -P "%DOWNLOAD_DIR%"
7z x "%DOWNLOAD_DIR%%SDL2%" -y -o%OUTPUT_DIR%
del /F /Q %DOWNLOAD_DIR%%SDL2%
正如你所看到的,我对CMake仍然"有点"陌生,但我正在努力学习。
Oof.关于你的CMakeLists的一切都是错误的。
-
永远不要在你的CMakeList中设置
CMAKE_CXX_FLAGS
.txt -
切勿使用
include_directories
或link_directories
-
切勿在没有可见性说明符的情况下使用
target_link_libraries
。 - 切勿手动设置库的路径。
- 不要将目标名称设置为与项目名称相等。这是毫无意义的复杂性和糟糕的风格。
这就是您所需要的:
cmake_minimum_required(VERSION 3.16)
project(Vivaria VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(SDL2 REQUIRED)
add_executable(Vivaria vivaria.cpp)
target_link_libraries(Vivaria PRIVATE SDL2::SDL2)
您的代码也有错误。您需要将此行添加到文件顶部
#define SDL_MAIN_HANDLED
首先,使用 vcpkg 安装 SDL2。然后,通过上述更改,它使用以下命令为我编译和运行:
> mkdir build
> cd build
> cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=X:/path/to/vcpkg.cmake ..
感谢齐瓦列夫! 在源文件中设置宏SDL_MAIN_HANDLED
解决了该问题。
#define SDL_MAIN_HANDLED // insert this
#include <iostream>
#include "SDL.h"
int main() {
if (SDL_Init(SDL_INIT_VIDEO) != 0){
std::cout << "Hello world" << std::endl;
return 1;
}
std::cout << "Hello world 2" << std::endl;
SDL_Quit();
return 0;
}
相关文章:
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 将 SDL2 与 CMake 链接起来
- 如何在应用程序子项目中将静态库与gradle子项目链接起来
- 尝试将 sfml 和 c++ 与 Windows 10 上的可移植 vscode 链接起来
- 将Qt应用程序与CMake和Visual Studio链接起来
- 如何将libc++与调试符号链接起来?
- 在Qt Creator中将Lua与C++链接起来
- 将 c++ 与 python 链接起来
- 是否可以将同一组源数据与不同的表模型链接起来?
- 在将C全局变量与C 代码链接起来的麻烦
- 将libstdc 静态链接起来是一个很好的做法
- 如何将函数的整数大小与数组的实际大小链接起来?C++
- 如何将 c++ 代码与 "libguile" "guile-1.8.8" 链接起来?
- 将 OpenCV 库与 Eclipse Ubuntu 链接起来
- 使用 JNI 静态地将 Java 与C++链接起来
- C++如何将我的主类与我的头文件链接起来
- 如何将 aws-sdk-cpp 与 CMake 链接起来
- 我怎么能说视觉工作室将库与我的项目链接起来
- 将 mingw dll 与 Windows DLL 链接起来
- 将问题与定义为静态的存储类链接起来