使用 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 时它们存在冲突,但这并不重要这个问题。
当我 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 时它们存在冲突,但这并不重要这个问题。