Из компилируешь a.cpp и b.cpp, а затем просто используешь их объектные файлы
пример на Makefile
a.o: a.cpp
gcc -c a.cpp -o a.o
b.o: b.cpp
gcc -c b.cpp -o b.o
tests.exe: a.o b.o
gcc a.o b.o test_main.cpp -o tests.exe
app.exe: a.o b.o
gcc a.o b.o app_main.cpp -o app_main.exe
как-то так
UPD: если про CMake, то используй OBJECT библиотеку
add_library(common OBJECT a.cpp b.cpp)
add_executable(tests PRIVATE tests_main.cpp $<TARGET_OBJECTS:common>)
add_executable(app PRIVATE app_main.cpp $<TARGET_OBJECTS:common>)