in reply to using a sub routing as an argument

Your clean routine will never run unless @ARGV does not contain "clean" or anything else. @ARGV in scalar context will evaluate to the number of elements in @ARGV ( that's the reason perl doesn't have or need $ARGC). The '==' comparison puts its arguments in numeric context. The numification of 'clean' is zero. Therefore you will call clean() only if @ARGV is empty.

You can detect the presence of build targets with grep {$_ eq $target} @ARGV or by @hash{@ARGV} = (); clean() if exists $hash{'clean'};, or you can have a look at the Getopt family of modules.

ExtUtils::MakeMaker is really very good at this sort of thing; it relies on make to do the heavy lifting. The trouble is that POSIX-standard make is not shipped with some OS and that many authors use gnu make extensions that other makes (standard or not) do not understand.

After Compline,
Zaxo