There is a simple solution: make variables that you can pass on the command line. They take precedence over the definitions in the Makefile.
$ cat Makefile
SRCS = $(filter-out main,$(patsubst %.cpp,%,$(wildcard *.cpp)))
main: main.o $(patsubst %,%.o,$(SRCS))
$(CXX) -o $@ $^
clean:
rm -f $(wildcard *.o) main
Then, if you want to link only a and b:
$ make SRCS="a b"
c++ -c -o main.o main.cpp
c++ -c -o a.o a.cpp
c++ -c -o b.o b.cpp
c++ -o main main.o a.o b.o
If you want to link only c and d:
$ make clean
rm -f a.o b.o main.o main
$ make SRCS="c d"
c++ -c -o main.o main.cpp
c++ -c -o c.o c.cpp
c++ -c -o d.o d.cpp
c++ -o main main.o c.o d.o
And the default:
$ make clean
rm -f c.o d.o main.o main
$ make
c++ -c -o main.o main.cpp
c++ -c -o a.o a.cpp
c++ -c -o b.o b.cpp
c++ -c -o c.o c.cpp
c++ -c -o d.o d.cpp
c++ -o main main.o a.o b.o c.o d.o
If the default does not make sense (e.g. because methods are defined in several source files), change the default value of SRCS in the Makefile:
SRCS = a b
Note: do not mix up make variables, which definition appears after the make command on the command line: make ... VAR=VALUE ... and the environment variables that you can pass to the make process: VAR=VALUE make .... There are relations between the two but they are completely different things.