Question about unity build and interface library / ODR

Let’s take the following example:

add_library(tw_base INTERFACE)
target_sources(tw_base INTERFACE Data.cpp)
target_include_directories(tw_base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(tw_base PROPERTIES PUBLIC_HEADER Data.h)

add_library(tw::base ALIAS tw_base)

    add_library(tw_base_tests INTERFACE)
    target_sources(tw_base_tests INTERFACE tests/DataTests.cpp)
    target_link_libraries(tw_base_tests INTERFACE tw::base)
    add_library(tw::base_tests ALIAS tw_base_tests)
add_library(MyAwesomeStaticLib sources...)
target_link_libraries(MyAwesomeStaticLib PUBLIC tw::base)

Later in tests folder:

add_executable(tests ${test_sources})
target_link_libraries(tests gtest_main MyAwesomeStaticLib tw::base_tests)

Why Data.cpp is included in multiple unity files (tests sources and lib sources) ? I would like Data.cpp to be compiled in unity build only for MyAwesomeStaticLib

I would like Data.cpp to be compiled only on MyAwesomeStaticLib and not the unit test target, Any hints on how to do that properly?

Why are tw_base and tw_base_tests defined as INTERFACE libraries? Why not SHARED or STATIC?

If you want Data.cpp to be compiled only for MyAwesomeStaticLib, why is it added to another target (tw_base)?

You can get rid of the double building of Data.c if you have tw_base_tests depend on MyAwesomeStaticLib and not on tw::base directly, and if you have MyAwesomeStaticLib depend on tw::base as a PRIVATE dependency, and not a PUBLIC one.

When you have a source file in an INTERFACE library, then that source file will be added to anything that depends on it. And when you have a PUBLIC dependency like that, then anything that was inherited from the dependency will also propagate to anything that depends on the target, so everything that depends on MyAwesomeStaticLib will also get built with Data.c.