I have a C++ project with CMake as build system.
I am using the dependencies SDL2 and SDL2_image in this project. It was building fine, when adding this dependencies via FetchContent
. But I wanted to transition to using find_package
so I don't have to build all the dependencies on every rebuild.
So I moved everything to find_package
and installed sdl2
and sdl2-image
with vcpkg.
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
)
Now my problem is, as soon as I build this project, CMake complains it can't find the target SDL2_image::SDL2_image
Build
ā 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.
I can't figure out, why CMake won't find the target SDL2_image::SDL2_image
. It is listed in the vcpkg install output as one of the available targets.
When I install the dependencies through pacman, CMake has no problem finding both packages and their targets (given that vcpkg is not passed in CMAKE_TOOLCHAIN_FILE). But I still need to use vcpkg on other machines...
One curiosity I found, was that when I try to link to SDL2_image::SDL2_image-static, the build succeeds. But I want to link to the shared library. (As far as I understood there, if I would link to SDL2_image::SDL2_image-static, it would not use the users SDL installation but the SDL2_image code would just be compiled into my app?).
Also it just seems weird, because given the usage text for sdl2-image (see Build), it is mentioned that if the target SDL2_image::SDL2_image
exists, both SDL2_image::SDL2_image
and SDL2_image::SDL2_image-static
should be available?
So where exactly does my problem lie? Did I misconfigure anything? If it is a bug, then how come no one else seems to have this problem?
Original answer from Petruska on discource.libsdl.ord
Vcpkg defaults to building static libraries on Linux and shared libraries on Windows. That's why the usage text from SDL2 recommends the 'complex' target_link_libraries with the if else. (also explains, why I couldn't reproduce it on Windows...) So this way, you can build on multiple platforms and it just defaults to whatever is available.
So by changing the CMakeLists.txt to the following, I was able to build the project:
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> )