In our projects we use a “simple” way of yours – add_library with both headers and sources.
If you add only sources, then you won’t see headers in IDE-generated project.
However, when installing, we have to do it like that, using two install commands:
install(TARGETS library_name
LIBRARY DESTINATION lib)
install(FILES ${PUBLIC_HEADERS}
DESTINATION include/library_name)
If you want to do it as a single command, you can use set_target_properties with PUBLIC_HEADER, as you suggested.
Then, this kind of install is possible:
install(TARGETS library_name
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include/library_name)
Choose the one you like the most and stick to it.