TL;DR don't try to do this
$ make run arg
instead create script build_and_run_prog.sh:
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
and do this:
$ ./build_and_run_prog.sh arg
Read on for some explanation of why this is the most reasonable choice and why the other alternatives are best avoided
Answer to the stated question: how to pass arguments to a make target
you can use a variable in the recipe
run: prog
    ./prog $(var)
then pass a variable assignment as an argument to make
$ make run var=arg
this will execute ./prog arg.
But beware of pitfalls.
Most notably to awkwardness when passing arguments with spaces. You will have to do it like this:
$ make run var="foo bar\ baz"
this will execute ./prog foo "bar baz".
I will elaborate about the pitfalls of this method and others further below.
Answer to the assumed intention behind your question: You want to run prog with some arguments but have it rebuild before running if necessary.
Create a script which rebuilds if necessary then runs prog with args
build_and_run_prog.sh:
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
This script makes the intention very clear. It uses make to do what it is good for: building. It uses a shell script to do what it is good for: batch processing.
Plus you can do whatever else you might need with the full flexibility and expressiveness of a shell script without all the caveats of a makefile.
Also the calling syntax is now practically identical:
$ ./build_and_run_prog.sh foo "bar baz"
compared to:
$ ./prog foo "bar baz"
contrast to
$ make run var="foo bar\ baz"
Background explanation of how make handles arguments:
Make is not designed to pass arguments to a target. All arguments on the command line are interpreted either as a goal (a.k.a. target), as an option, or as a variable assignment.
so if you run this:
$ make run foo --wat var=arg
make will interpret run and foo as goals (targets) to update according to their recipes. --wat as an option for make. And var=arg as a variable assignment for make.
the only chance you have to pass information from the command line to use inside a recipe is via variable assignment.
for more details see the gnu manual on how to run make
Why I recommend against variable assignment
$ make run var=arg
and the variable in the recipe
run: prog
    ./prog $(var)
This is the most "correct" and straightforward way to pass arguments to a recipe. but while it can be used to run a program with arguments it is certainly not designed to be used that way. See the gnu manual on overriding
In my opinion this has one big disadvantage: what you want to do is run prog with argument arg. but instead of writing:
$ ./prog arg
you are writing:
$ make run var=arg
this gets even more awkward when trying to pass multiple arguments or arguments containing spaces:
$ make run var="foo bar\ baz"
./prog foo bar\ baz
argcount: 2
arg: foo
arg: bar baz
compare to:
$ ./prog foo "bar baz"
argcount: 2
arg: foo
arg: bar baz
for the record this is what my prog looks like:
#! /bin/sh
echo "argcount: $#"
for arg in "$@"; do
  echo "arg: $arg"
done
also note that you should not put $(var) in quotes in the makefile:
run: prog
    ./prog "$(var)"
because then prog will always get just one argument:
$ make run var="foo bar\ baz"
./prog "foo bar\ baz"
argcount: 1
arg: foo bar\ baz
All this is why I recommend against this route.
For completeness here are some other methods to "pass arguments to make run".
Method 1:
run: prog
    ./prog $(filter-out $@, $(MAKECMDGOALS))
%:
    @true
filter out current goal from list of goals. create catch all target (%) which does nothing to silently ignore the other goals.
Method 2:
ifeq (run, $(firstword $(MAKECMDGOALS)))
  runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
  $(eval $(runargs):;@true)
endif
run:
    ./prog $(runargs)
if the target is run then remove the first goal and create do nothing targets for the remaining goals using eval.
both will allow you to write something like this
$ make run arg1 arg2
problems of method 1:
- Arguments that start with a dash will be interpreted by make and not passed as a goal. -   $ make run --foo --bar
 - workaround -   $ make run -- --foo --bar
 
- Arguments with an equal sign will be interpreted by make and not passed -   $ make run foo=bar
 - no workaround 
- Arguments with spaces is awkward -   $ make run foo "bar\ baz"
 - no workaround 
- If an argument happens to be - run(equal to the target) it will also be removed
 -   $ make run foo bar run
 - will run - ./prog foo barinstead of- ./prog foo bar run
 - workaround possible with method 2 
- If an argument is a legitimate target it will also be run. -   $ make run foo bar clean
 - will run - ./prog foo bar cleanbut also the recipe for the target- clean(assuming it exists).
 - workaround possible with method 2 
- When you mistype a legitimate target it will be silently ignored because of the catch all target. -   $ make celan
 - will just silently ignore - celan.
 - workaround is to make everything verbose. so you see what happens. but that creates a lot of noise for the legitimate output. 
problems of method 2:
- If an argument has same name as an existing target then make will print a warning that it is being overwritten. - no workaround that I know of 
- Arguments with an equal sign will still be interpreted by make and not passed - no workaround 
- Arguments with spaces is still awkward - no workaround 
- Arguments with space breaks - evaltrying to create do nothing targets.
 - workaround: create the global catch all target doing nothing as above. with the problem as above that it will again silently ignore mistyped legitimate targets. 
- it uses - evalto modify the makefile at runtime. how much worse can you go in terms of readability and debugability and the Principle of least astonishment.
 - workaround: don't! 
I have only tested using gnu make. other makes may have different behaviour.
gnu make manual
https://www.gnu.org/software/make/manual/html_node/index.html