A reliable way, which doesn't depend on parsing debug output (which is not documented, thus subject to change) is to run make in --query and --print-database modes together, then grep for the .DEFAULT_GOAL assignment. This variable, along with some examples and other special variables, is documented at Special Variables.
make -qp | grep ^".DEFAULT_GOAL := " | tail -n 1
Since --query + --print-database mode does not try to make (not even resolve dependencies and file freshness), it has two advantages compared with Roger's answer:
- no recipes are run
- directories are not recursed, no sub-makes are spawned. You get the
.DEFAULT_GOAL of the current directory's Makefile
The tail -n 1 bit is needed to reliably get correct output. The output of something like $(info .DEFAULT_GOAL := fake-goal) in the makefile is sent to stdout first. The variables and rules are printed last, after the makefile is fully parsed and variables expanded. Hence, the last instance of .DEFAULT_GOAL on stdout is the genuine one you're looking for.
Caution: A makefile is effectively a script executed on parse, whether in --query/--dry-run mode or not. Functions are expanded, so something like $(shell BOOM) is expanded before at makefile parse time. It's not possible to reliably parse a makefile and determine the default target without executing anything. Only run make on makefiles you trust, or sandbox it.
Related questions: