This could work with the simple case you've laid out, assuming lib is another target created within the same CMake build tree. You could use get_target_property() to get the LINK_LIBRARIES property list for TargetA and TargetB. If lib is in the list of first-level link dependencies, then you can add the compile definition to lib.
# Get the list of first-level link dependencies for TargetA and TargetB.
get_target_property(TARGETA_LIBS TargetA LINK_LIBRARIES)
get_target_property(TARGETB_LIBS TargetB LINK_LIBRARIES)
# Loop through the TargetA dependencies.
foreach(LIB ${TARGETA_LIBS})
# Was the 'lib' library added as a dependency to TargetA?
if (${LIB} STREQUAL lib)
# Yes, so add the compile definitions to 'lib'.
target_compile_definitions(${LIB} PRIVATE DEF_A)
endif()
endforeach()
# Loop through the TargetB dependencies.
foreach(LIB ${TARGETB_LIBS})
# Was the 'lib' library added as a dependency to TargetB?
if (${LIB} STREQUAL lib)
# Yes, so add the compile definitions to 'lib'.
target_compile_definitions(${LIB} PRIVATE DEF_B)
endif()
endforeach()
Note, this only works if lib is a first-level dependency of the target, it does not search dependencies recursively, as shown in this answer. Also, if lib is an interface library, you'll have to get the INTERFACE_LINK_LIBRARIES property instead.
EDIT Based on answer feedback: If the compile definitions DEF_A and DEF_B are mutually exclusive in the lib target. The cleanest approach may be to create a separate lib target, one catered for TargetA and another catered for TargetB. This could look something like this:
set(LIB_SOURCES
Class1.cpp
...
)
# Create the 'lib' target to link to TargetA.
add_library(lib_forTargetA SHARED ${LIB_SOURCES})
target_compile_definitions(lib_forTargetA PRIVATE DEF_A)
# Create the 'lib' target to link to TargetB.
add_library(lib_forTargetB SHARED ${LIB_SOURCES})
target_compile_definitions(lib_forTargetB PRIVATE DEF_B)