Windows下使用CMake动态加载C++依赖(SDL2)的优雅方案
解决Windows下FetchContent引入SDL2后运行时找不到DLL的优雅方案
以下几种方案无需手动复制DLL,且能适配跨平台开发需求:
1. 利用CMake生成器表达式自动复制运行时DLL(CMake 3.21+)
CMake 3.21及以上版本提供了$<TARGET_RUNTIME_DLLS>生成器表达式,可自动收集目标依赖的所有运行时DLL,并复制到目标输出目录。在你的目标可执行文件定义后添加以下代码:
add_executable(YourGame main.cpp) # 链接SDL2目标 target_link_libraries(YourGame PRIVATE SDL2::SDL2 SDL2::SDL2main) # 自动复制依赖的DLL到exe输出目录 if(WIN32) add_custom_command(TARGET YourGame POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:YourGame> $<TARGET_FILE_DIR:YourGame> COMMAND_EXPAND_LISTS ) endif()
这个方案跨平台友好,Windows下自动处理DLL,MacOS下不会执行多余操作,完全自动化。
2. 配置调试环境变量(针对Visual Studio)
如果仅需在调试阶段解决问题,无需复制DLL,可以通过设置Visual Studio的调试环境变量,将SDL2的DLL所在目录加入PATH:
add_executable(YourGame main.cpp) target_link_libraries(YourGame PRIVATE SDL2::SDL2 SDL2::SDL2main) if(WIN32 AND MSVC) # 获取SDL2 DLL所在目录 get_target_property(SDL2_DLL_DIR SDL2::SDL2 IMPORTED_LOCATION) get_filename_component(SDL2_DLL_DIR ${SDL2_DLL_DIR} DIRECTORY) # 设置调试时的PATH环境变量 set_target_properties(YourGame PROPERTIES VS_DEBUGGER_ENVIRONMENT "PATH=%PATH%;${SDL2_DLL_DIR}" ) endif()
此方案无需复制文件,直接让调试器找到DLL,适合开发阶段快速调试,MacOS下无影响。
3. 调整SDL2的构建输出目录
在FetchContent引入SDL2时,指定其构建输出目录与你的项目目标目录一致,这样SDL2编译生成的DLL会直接输出到exe所在目录:
include(FetchContent) FetchContent_Declare( SDL2 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git GIT_TAG release-2.28.5 # 使用你需要的版本 ) # 在SDL2配置前设置输出目录 set(SDL2_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} CACHE INTERNAL "") set(SDL2_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} CACHE INTERNAL "") FetchContent_MakeAvailable(SDL2) add_executable(YourGame main.cpp) target_link_libraries(YourGame PRIVATE SDL2::SDL2 SDL2::SDL2main)
这种方式从源头解决问题,SDL2编译后的DLL直接和exe同目录,无需额外复制操作,跨平台通用。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

