There should be a target_include_directories(SDL2 PUBLIC <$BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include), but that must be in the same CMakeLists that defines the library, which require changing the SDL's CMakeLists.

So, one solution could be to create an imported target to attach this path and l ink to it instead:

There should be a target_include_directories(SDL2 PUBLIC <$BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include), but that must be in the same CMakeLists that defines the library, which require changing the SDL's CMakeLists.

That's not actually true. You can call target_include_directories() on any target, not just those created in the current scope. In fact, all of the target_...() commands except target_link_libraries() can do this (and it was recently agreed that we should remove the restriction on target_link_libraries() too). This means if a project like SDL fails to set INTERFACE properties for header search paths, compiler defines, etc. you can add them yourself from outside the project. Obviously it's better if the project itself can be updated to do it, but in the meantime your own project can add the missing things.

So, one solution could be to create an imported target to attach this path and l ink to it instead: