使用 CMake 获取、构建和 link 的 SDL2 因未定义的“floor”引用而失败

Fetch, build and link of SDL2 fails with undefined `floor` references using CMake

当我 link 使用 SDL2

编写程序时出现以下错误
/usr/bin/ld: ../_deps/sdl2_content-build/libSDL2d.a(SDL_stdlib.c.o): in function `SDL_floor_REAL':
/home/user/myprogram/cmake-build-debug/_deps/sdl2_content-src/src/stdlib/SDL_stdlib.c:247: undefined reference to `floor'

我制作了一个包含的 FetchSDL2.cmake 文件,理论上应该可以获取并构建和使用它:

FetchContent_Declare(
    sdl2_content
    URL https://www.libsdl.org/release/SDL2-2.0.12.tar.gz
    URL_HASH MD5=783b6f2df8ff02b19bb5ce492b99c8ff
)

FetchContent_GetProperties(sdl2_content)
if(NOT sdl2_content_POPULATED)
  FetchContent_Populate(sdl2_content)
  if(ANDROID)
      set(SDL_SHARED ON CACHE BOOL "shared")
      set(SDL_STATIC ON CACHE BOOL "static")
      add_subdirectory(${sdl2_content_SOURCE_DIR} ${sdl2_content_BINARY_DIR} EXCLUDE_FROM_ALL)
      add_library(SDL2::SDL2 ALIAS SDL2)
      add_library(SDL2::SDL2main ALIAS SDL2main)
  elseif(WIN32 OR LINUX OR MACOS)
      set(SDL_SHARED OFF CACHE BOOL "no shared")
      set(SDL_STATIC ON CACHE BOOL "static")
      set(SDL_STATIC_PIC ON CACHE BOOL "Static version of the library should be built with Position Independent Code")
      set(SDL_SHARED OFF)
      set(SDL_STATIC ON)
      set(SDL_STATIC_PIC ON)
      set(FORCE_STATIC_VCRT ON CACHE BOOL "static windows static vcrc")
      add_subdirectory(${sdl2_content_SOURCE_DIR} ${sdl2_content_BINARY_DIR} EXCLUDE_FROM_ALL)
      add_library(SDL2::SDL2 ALIAS SDL2-static)
      add_library(SDL2::SDL2main ALIAS SDL2main)
  endif()

  if(NOT EXISTS "${sdl2_content_BINARY_DIR}/include/SDL2")
      execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${sdl2_content_SOURCE_DIR}/include ${sdl2_content_BINARY_DIR}/include/SDL2)
  endif()

  find_package(LibM)
  set(SDL2_INCLUDE_HINTS "${sdl2_content_BINARY_DIR}/include/" "${sdl2_content_BINARY_DIR}/include/SDL2/")
  set(SDL2_LIB_HINTS "${sdl2_content_BINARY_DIR}/")
  find_package(SDL2)
  list(APPEND SDL2_INCLUDE_DIRS "${sdl2_content_BINARY_DIR}/include/SDL2/")
  list(APPEND SDL2_INCLUDE_DIRS "${sdl2_content_BINARY_DIR}/include/")
  list(APPEND SDL2_INCLUDE_DIRS "${LIBM_INCLUDE_DIRS}")
  list(APPEND SDL2_LIBRARY_DIRS "${sdl2_content_BINARY_DIR}/")
  list(APPEND SDL2_LIBRARIES SDL2::SDL2)
  list(APPEND SDL2_LIBRARIES "${LIBM_LIBRARIES}")
endif()

但我一直收到上面的错误。我确实有 LibM,并且所有其他数学函数 links 都正确。我在 Ubuntu 20.04 .

你能帮忙解决这个问题,让它正确获取 SDL2 吗?我没有安装它的原因是这个脚本将被 CMake 在一些没有包管理器的平台上使用。

我想通了。原来 SDL2 有两个 headers 同名 SDL_config.h。您要包含的是 CMake 生成的,而不是库附带的。

下面是我正确删除和安装正确的CMake文件headers。使用 SDL 2.0.12 测试。

FetchContent_Declare(
    sdl2_content
    URL https://www.libsdl.org/release/SDL2-2.0.12.tar.gz
    URL_HASH MD5=783b6f2df8ff02b19bb5ce492b99c8ff
)

FetchContent_GetProperties(sdl2_content)
if(NOT sdl2_content_POPULATED)
    FetchContent_Populate(sdl2_content)
    if(ANDROID)
        set(SDL_SHARED ON CACHE BOOL "shared")
        set(SDL_STATIC OFF CACHE BOOL "static")
        add_subdirectory(${sdl2_content_SOURCE_DIR} ${sdl2_content_BINARY_DIR} EXCLUDE_FROM_ALL)
        add_library(SDL2::SDL2 ALIAS SDL2)
    elseif(WIN32 OR LINUX OR MACOS)
        set(SDL_SHARED OFF CACHE BOOL "shared")
        set(SDL_STATIC ON CACHE BOOL "static")
        set(SDL_STATIC_PIC ON CACHE BOOL "Static version of the library should be built with Position Independent Code")
        set(SDL_SHARED OFF)
        set(SDL_STATIC ON)
        set(SDL_STATIC_PIC ON)
        if(LINUX)
            set(SNDIO_SHARED ON CACHE BOOL "static")
            set(SNDIO_SHARED ON)
        endif()
        set(FORCE_STATIC_VCRT ON CACHE BOOL "static windows static vcrc")
        add_subdirectory(${sdl2_content_SOURCE_DIR} ${sdl2_content_BINARY_DIR} EXCLUDE_FROM_ALL)
        add_library(SDL2::SDL2 ALIAS SDL2-static)
    endif()
    add_library(SDL2::SDL2main ALIAS SDL2main)

    file(GLOB INCLUDE_FILES ${sdl2_content_SOURCE_DIR}/include/*.h)
    file(GLOB BIN_INCLUDE_FILES ${sdl2_content_BINARY_DIR}/include/*.h)
    foreach(_FNAME ${BIN_INCLUDE_FILES})
        get_filename_component(_INCNAME ${_FNAME} NAME)
        list(REMOVE_ITEM INCLUDE_FILES ${sdl2_content_SOURCE_DIR}/include/${_INCNAME})
    endforeach()
    list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES})

    if(NOT EXISTS "${sdl2_content_BINARY_DIR}/include/SDL2")
        file(MAKE_DIRECTORY "${sdl2_content_BINARY_DIR}/include/SDL2")
        file(COPY ${INCLUDE_FILES}  DESTINATION "${sdl2_content_BINARY_DIR}/include/SDL2")
    endif()
    include_directories("${sdl2_content_BINARY_DIR}/include")

    if(EXISTS "${sdl2_content_SOURCE_DIR}/android-project")
        file(REMOVE_RECURSE "${sdl2_content_SOURCE_DIR}/android-project")
    endif()

    file(COPY CMake/Extra/sdl2-config.cmake DESTINATION ${sdl2_content_BINARY_DIR})
    set(SDL2_DIR ${sdl2_content_BINARY_DIR})
    list(APPEND SDL2_INCLUDE_DIRS "${sdl2_content_BINARY_DIR}/include/SDL2/")
    list(APPEND SDL2_INCLUDE_DIRS "${sdl2_content_BINARY_DIR}/include/")
    list(APPEND SDL2_LIBRARY_DIRS "${sdl2_content_BINARY_DIR}/")
    list(APPEND SDL2_LIBRARIES SDL2::SDL2)
    list(APPEND SDL2_LIBRARIES SDL2::SDL2main)
endif()

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

注意:我另外删除了 Android 项目文件,因为当我在 Android 上使用 运行 SDL2 时它们存在冲突,但这并不重要这个问题。