通过获取内容使用SDL2和SDL2_Image进行cmake

zxlwwiss  于 2023-03-02  发布在  其他
关注(0)|答案(2)|浏览(206)

bounty将在3天后过期。回答此问题可获得+50声望奖励。Juan Medina希望引起更多人对此问题的关注:我真的很好奇这是怎么做到的!

我有一个通过FetchContent使用SDL的小cmake项目,它只使用SDL就能很好地工作。

cmake_minimum_required(VERSION 3.24)
project(sdl_test)

set(CMAKE_CXX_STANDARD 20)

include(FetchContent)
Set(FETCHCONTENT_QUIET FALSE)

FetchContent_Declare(
        SDL2
        GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
        GIT_TAG release-2.26.3
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(SDL2)
include_directories(${SDL2_SOURCE_DIR}/include})

add_executable(sdl_test main.cpp)
target_link_libraries(sdl_test SDL2::SDL2main SDL2::SDL2-static)

我尝试使用相同的方法来包含SDL_Image,但无法使其工作。

cmake_minimum_required(VERSION 3.24)
project(sdl_test)

set(CMAKE_CXX_STANDARD 20)

include(FetchContent)
Set(FETCHCONTENT_QUIET FALSE)

FetchContent_Declare(
        SDL2
        GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
        GIT_TAG release-2.26.3
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(SDL2)
include_directories(${SDL2_SOURCE_DIR}/include})

FetchContent_Declare(
        SDL2_image
        GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
        GIT_TAG release-2.6.3
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(SDL2_image)
include_directories(${SDL2IMAGE_INCLUDE_DIRS}/include})

add_executable(sdl_test main.cpp)
target_link_libraries(sdl_test SDL2::SDL2main SDL2::SDL2-static SDL2_image::SDL2_image-static)

产生以下错误:

CMake Error: install(EXPORT "SDL2ImageExports" ...) includes target "SDL2_image" which requires target "SDL2" that is not in any export set.
CMake Error at CMakeLists.txt:30 (target_link_libraries):
  Target "sdl_test" links to:

    SDL2_image::SDL2_image-static

  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.
  • 注意:也许有些人不喜欢使用FetchContent,但是我喜欢它,并且过去一直在为许多其他依赖项使用它,所以我正在尝试使这种方法工作。*
qco9c6ql

qco9c6ql1#

我在这里概述的答案只是一个可能的解决方案,它可能不起作用。但值得一试。使其起作用的最好方法是不使用SHALLOW fetch,但我在这里假设您不需要。更正@user。

    • 可能的解决方案:**

评论中的大多数人都关注错误信息中的"错误"部分,你应该关注的是前两行,即:

CMake Error: install(EXPORT "SDL2ImageExports" ...) includes target "SDL2_image" which requires target "SDL2" that is not in any export set.
CMake Error at CMakeLists.txt:30 (target_link_libraries):

因为找不到目标,所以链接的实际库并不存在,这就是BUILD_SHARED_LIBS选项不起任何作用的原因。
它说SDL2_image需要目标SDL2,这是在前面的FetchContent调用中定义的,但是在构建时这对另一个是不可用的,现在真正的问题是,如何使它可用。
我相信唯一的方法是一种"hacky"方法,让我们看看SDL_Image s CMakeLists.txt是什么样子的,特别是下面这行代码:第748行。
似乎SDL2作为一个软件包被称为SDL2main,请注意,在versions 3.0.0+中它只是SDL3
因此,实现这一点的最佳机会可能是将第一个FetchContent_Declare修改为这样(注意,您需要CMake 3.24+):

FetchContent_Declare(
        SDL2main # <--- new name of our target
        GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
        GIT_TAG release-2.26.3
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE
        OVERRIDE_FIND_PACKAGE #<--- and we also need to add this
)

这应该会覆盖后续的find_package(SDL2main)调用,并可能修复您的问题。

    • 最后一个选项:**如果以上方法不起作用,您可以"不构建" SDL2_Image示例,即强制SDL2IMAGE_SAMPLESFalse
juud5qan

juud5qan2#

我在SLD_Image存储库上创建了一个问题,他们给予了下面的答案,实际上是有效的。

  • SDL2_image的CMake脚本仅构建共享库或静态库,不能同时构建两者。*因此,您需要将BUILD_SHARED_LIBS设置为一个错误值。
  • 此外,您需要禁用SDL2_image的安装目标(git中已修复)。*
  • 因此,您的cmake脚本应变为:*
cmake_minimum_required(VERSION 3.24)
project(sdl_test)

set(CMAKE_CXX_STANDARD 20)

include(FetchContent)
Set(FETCHCONTENT_QUIET FALSE)

FetchContent_Declare(
        SDL2
        GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
        GIT_TAG release-2.26.3
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(SDL2)

FetchContent_Declare(
        SDL2_image
        GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
        GIT_TAG release-2.6.3
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE
)

# START ADDITION
set(SDL2IMAGE_INSTALL OFF)
set(BUILD_SHARED_LIBS FALSE)
# END ADDITION

FetchContent_MakeAvailable(SDL2_image)

add_executable(sdl_test main.cpp)
target_link_libraries(sdl_test SDL2::SDL2main SDL2::SDL2-static SDL2_image::SDL2_image-static)

它们进一步澄清了行为。

  • SDL2能够创建共享库和静态库,可通过SDL_SHAREDSDL_STATIC进行配置。**默认情况下两者都启用。*SDL2_image一次只能配置一个(使用BUILD_SHARED_LIBS)。
  • SDL3的默认值已更改:SDL_SHAREDSDL_STATICBUILD_SHARED_LIBS初始化(在第一次配置期间)。*如果未定义BUILD_SHARED_LIBS,则仅启用SDL_SHARED如果定义了BUILD_SHARED_LIBS,则可以构建t决定哪一个。SDL_SHAREDSDL_STATIC仍是最终选项。
  • 尚未实施,但SDL3_image可能会遵循与SDL3相同的行为,并且能够构建共享配置和静态配置。*

相关问题