英文:
cmake using SDL2 and SDL2_Image via FetchContent
问题
以下是您提供的代码的中文翻译部分:
# 我有一个小的CMake项目,通过FetchContent使用SDL,这只适用于SDL。
cmake_minimum_required(VERSION 3.24)
project(sdl_test)
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
Set(FETCHCONTENT_QUIET FALSE)
# 声明要获取的SDL2库
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)
# 链接SDL2库
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)
# 获取SDL2库
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})
# 获取SDL2_Image库
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)
# 链接SDL2和SDL2_Image库
target_link_libraries(sdl_test SDL2::SDL2main SDL2::SDL2-static SDL2_image::SDL2_image-static)
产生以下错误:
CMake错误:安装(EXPORT "SDL2ImageExports" ...) 包括目标 "SDL2_image",需要目标 "SDL2",但它不在任何导出集中。
CMake错误位于CMakeLists.txt:30 (target_link_libraries):
目标 "sdl_test" 链接到:
SDL2_image::SDL2_image-static
但未找到该目标。可能的原因包括:
* 目标名称中存在拼写错误。
* 丢失了IMPORTED目标的find_package调用。
* 缺少ALIAS目标。
注意:也许有些人不喜欢使用FetchContent,但我喜欢它,并在过去使用它来获取许多其他依赖项,因此我正在尝试使这种方法起作用。
英文:
I've a small cmake project that uses SDL via FetchContent, this work well with just 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)
I try to use the same approach to include SDL_Image, however I can not get it to work.
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)
Produce the following error:
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.
Note: Maybe some people dislike using FetchContent, however I like it and been using for many other dependencies in the past, so I'm trying to make this approach to work.
答案1
得分: 0
可能的解决方案:
在评论中,大多数人关注错误消息的“错误”部分。您应该关注的是前两行,即:
CMake错误:install(EXPORT “SDL2ImageExports” ...) 包括需要目标“SDL2”的目标“SDL2_image”,而在任何导出集中都找不到它。
CMake错误在CMakeLists.txt:30(target_link_libraries)处:
由于找不到目标,您链接的实际库不存在。这就是为什么BUILD_SHARED_LIBS
选项无效的原因。
它说SDL2_image
需要目标SDL2
,该目标在先前的FetchContent
调用中定义,但在构建时对另一个目标不可用。现在真正的问题是如何使它可用。
我认为唯一的方法几乎是一种“hacky”方法。让我们看看SDL_Image
的CMakeLists.txt
是什么样子,特别是这一行:
第748行。
看起来SDL2
作为一个包被称为SDL2main
,请注意,在3.0.0+
版本中只是SDL3
。
因此,使这项工作的最佳机会可能是将第一个FetchContent_Declare
更改如下(请注意,您需要CMake 3.24+
):
FetchContent_Declare(
SDL2main # <---我们目标的新名称
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
GIT_TAG release-2.26.3
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
OVERRIDE_FIND_PACKAGE #<---我们还需要添加这个
)
这应该希望覆盖后续的find_package(SDL2main)
调用,并可能修复您的问题。
最后的选择: 如果上述方法不起作用,您可以只是“不构建”SDL2_Image
示例,即通过强制SDL2IMAGE_SAMPLES
为False
。
英文:
<strike>The answer that I'm outlining here is just a possible solution, it may not work. But it's worth a try. The best way to make this work is to not use the SHALLOW
fetch, but I assume here that you don't want that.</strike>
Correction from @user.
Possible solution:
Most of the people in the comments focus on the "wrong" part of the error message. What you should be focusing on are the first 2 lines, i.e.:
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):
Because the target is not found, the actual library that you link against doesn't exist. Hence why the BUILD_SHARED_LIBS
option doesn't do anything.
It says that SDL2_image
requires the target SDL2
which is defined in the previous FetchContent
invokation, but this isn't available to the other one during build time. The real question now is, how to make it available.
I believe the only way is pretty much a "hacky" way. Let's check what the SDL_Image
s CMakeLists.txt
looks like, specifically the line right here:
Line 748.
It seems to be that SDL2
as a package is referred to as SDL2main
, please note that in versions 3.0.0+
it's just SDL3
.
So the best chance at making this work would probably be to change the first FetchContent_Declare
as such (Note that you need 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
)
This should hopefully override subsequent find_package(SDL2main)
calls and might fix your issue.
Last option: if the above won't work, you could just "not build" the SDL2_Image
samples, i.e. by enforcing SDL2IMAGE_SAMPLES
to be False
.
答案2
得分: 0
他们在SDL_Image存储库上创建了一个问题,并提供了以下实际可行的答案。
CMake脚本SDL2_image仅构建共享库或静态库,而不是两者兼有。
因此,您需要将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
)
# 开始部分添加
set(SDL2IMAGE_INSTALL OFF)
set(BUILD_SHARED_LIBS FALSE)
# 结束部分添加
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_SHARED
和SDL_STATIC
进行配置。
默认情况下,两者都已启用。
SDL2_image一次只能配置一个(使用BUILD_SHARED_LIBS
)。
SDL3的默认设置已更改:SDL_SHARED
和SDL_STATIC
由BUILD_SHARED_LIBS
(在首次配置期间)初始化。
如果未定义BUILD_SHARED_LIBS
,则仅启用SDL_SHARED
。
如果定义了BUILD_SHARED_LIBS
,它可以构建决定哪个)。
无论哪种方式,SDL_SHARED
和SDL_STATIC
仍然是最终选项。
尚未实现,但SDL3_image可能会遵循与SDL3相同的行为,能够构建共享和静态配置。
英文:
I create an issue on SLD_Image repository, and they give the following answer, that actually work.
The CMake script of SDL2_image builds only a shared or static library, not both.
So you need to set BUILD_SHARED_LIBS to a false-ish value.
Also, you need to disable the installation targets of SDL2_image (this has been fixed in git).
So your cmake script should become:
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)
They clarify further the behaviour.
SDL2 is able to create a shared and static library, configurable through SDL_SHARED
and SDL_STATIC
.
Both are enabled by default.
SDL2_image is only able to configure one at a time (using BUILD_SHARED_LIBS
).
SDL3's default has changed: SDL_SHARED
and SDL_STATIC
are initialized by BUILD_SHARED_LIBS
(during first configuration).
If BUILD_SHARED_LIBS
is not defined, then only SDL_SHARED
is enabled.
If BUILD_SHARED_LIBS
is defined, it can build tdecides what one).
Either ways SDL_SHARED
and SDL_STATIC
remain the ultimate options.
It isn't implemented yet, but SDL3_image will probably follow the same behavior as SDL3 and be able to build both shared and static configurations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论