我有一个使用 CMake 作为构建系统的 C++ 项目。 我在这个项目中使用依赖项 SDL2 和 SDL2_image。通过
FetchContent
添加此依赖项时,构建得很好。但我想过渡到使用 find_package
,这样我就不必在每次重建时构建所有依赖项。
所以我将所有内容移至 find_package
并使用 vcpkg 安装了 sdl2
和 sdl2-image
。
vcpkg.json
{
"dependencies": [
"sdl2",
"sdl2-image"
],
"builtin-baseline": "1b65197e9393b9ca312c95731ebf9c53d776b8d2"
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(Sdl2App)
find_package(SDL2 CONFIG REQUIRED)
find_package(SDL2_image CONFIG REQUIRED)
add_executable(Sdl2App
"./main.cpp"
)
target_link_libraries(Sdl2App PRIVATE
SDL2::SDL2
SDL2_image::SDL2_image
)
现在我的问题是,当我构建这个项目时,CMake 抱怨它找不到目标
SDL2_image::SDL2_image
构建
➜ sdl2-build-error cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=/home/ascendise/Dev/vcpkg/scripts/buildsystems/vcpkg.cmake
-- Running vcpkg install
Detecting compiler hash for triplet x64-linux...
All requested packages are currently installed.
Total install time: 390 ns
sdl2 provides CMake targets:
find_package(SDL2 CONFIG REQUIRED)
target_link_libraries(main
PRIVATE
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
)
sdl2-image provides CMake targets:
find_package(SDL2_image CONFIG REQUIRED)
target_link_libraries(main PRIVATE $<IF:$<TARGET_EXISTS:SDL2_image::SDL2_image>,SDL2_image::SDL2_image,SDL2_image::SDL2_image-static>)
-- Running vcpkg install - done
-- Configuring done (0.8s)
CMake Error at CMakeLists.txt:10 (target_link_libraries):
Target "Sdl2App" links to:
SDL2_image::SDL2_image
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.
-- Generating done (0.0s)
CMake Generate step failed. Build files cannot be regenerated correctly.
我不明白,为什么 CMake 找不到目标
SDL2_image::SDL2_image
。它在 vcpkg 安装输出中列为可用目标之一。
当我通过 pacman 安装依赖项时,CMake 可以毫无问题地找到包及其目标(假设 vcpkg 未在 CMAKE_TOOLCHAIN_FILE 中传递)。但我还是需要在其他机器上使用vcpkg...
我发现的一个好奇心是,当我尝试链接到 SDL2_image::SDL2_image-static 时,构建成功。但我想链接到共享库。 (据我所知,如果我链接到 SDL2_image::SDL2_image-static,它不会使用用户的 SDL 安装,但 SDL2_image 代码只会编译到我的应用程序中?)。
而且这看起来很奇怪,因为给定 sdl2-image 的使用文本(请参阅构建),提到如果目标
SDL2_image::SDL2_image
存在,SDL2_image::SDL2_image
和 SDL2_image::SDL2_image-static
都应该可用?
那么我的问题到底出在哪里呢?我配置错误了吗?如果这是一个错误,那么为什么其他人似乎没有这个问题?
Petruska 在 Discource.libsdl.ord 上的原始答案
Vcpkg 默认在 Linux 上构建静态库,在 Windows 上构建共享库。这就是为什么 SDL2 的使用文本建议使用带有 if else 的“复杂”target_link_libraries。 (还解释了为什么我无法在 Windows 上重现它......) 这样,您就可以在多个平台上进行构建,并且它只是默认为可用的平台。
因此,通过将 CMakeLists.txt 更改为以下内容,我能够构建该项目:
cmake_minimum_required(VERSION 3.21) project(Sdl2App)
find_package(SDL2 CONFIG REQUIRED) find_package(SDL2_image CONFIG REQUIRED) add_executable(Sdl2App
"./main.cpp" )
target_link_libraries(Sdl2App PRIVATE
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
$<IF:$<TARGET_EXISTS:SDL2_image::SDL2_image>,SDL2_image::SDL2_image,SDL2_image::SDL2_image-static> )