test case for internal library (PUBLIC and PRIVATE)

I reference two project and add some dependent library.
The cmake tell us that using PRIVATE to protect our code

Background

main project bar
foo library

The bar execution will use the foo library
where foo use spdlog third party

Test case

test 1 .

PASS

# foo cmake
target_link_libraries(foo PRIVATE spdlog::spdlog)

target_include_directories(
  foo PUBLIC
    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
     ...
)
# foo.cpp
#include <spdlog/spdlog.h>

test 2.

Fail

# foo cmake
target_link_libraries(foo PRIVATE spdlog::spdlog)

target_include_directories(
  foo PUBLIC
    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
     ...
)
# foo.h
#include <spdlog/spdlog.h>
# error
can not open "spdlog/spdlog.h"

test 3.

PASS

# foo cmake
target_link_libraries(foo PUBLIC spdlog::spdlog)

target_include_directories(
  foo PUBLIC
    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
     ...
)
# foo.h
#include <spdlog/spdlog.h>

test 4

PASS

# foo cmake
target_link_libraries(foo PRIVATE spdlog::spdlog)

target_include_directories(
  foo PUBLIC
    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
     ...
    "$<BUILD_INTERFACE:${SPDLOG_INCLUDE_DIRS}>"
)
# foo.h
#include <spdlog/spdlog.h>

Question

In modern camke, we always use the imported target to link my program, so we don’t need to target_link_libraries. And cmake always suggest our code should be PRIVATE.

  1. Why does Test 1 work?

  2. When is the best time to use PRIVATE to protect code?

  3. Shall I always use PUBLIC for target_link_libraries and target_include_directories?

  4. Which test is the best?