cmakesdl-2vcpkg

SDL2_image::SDL2_image target was not found when installed with vcpkg


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?


Solution

  • 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> )