UPDATED
The OP's question was about the behavior of shell completion for make, looking for a way to generate target names from existing filenames using shell completion.
I focused my attention, incorrectly, on the intent to pass the filename as an argument to make when clearly the OP was looking for a way to generate a target name instead. My error.
With that incorrect focus in mind I wrote the following reply to help explain why passing the name of an existing file which is not a target produces the "Nothing to be done..." message. Although it may not have been the right reply for the OP's question in retrospect, it is done... So with this explanatory note and my apology for the noise, I will leave it in place for the closely related case which it does cover as I have seen it occur often enough, hopefully it will help someone...
A common perception is that make works on filenames and builds applications from source code, and that is wrong on both points! We come to expect such behavior because few of us frequently write rules for make, and make is smart enough to figure out what we really want it to do based on a few existing rules and a filename, often enough, that we come to think that is what it expects. And we use it most often to build from source, so we think that is just what it does.
But make is a command generator, not a compiler, and it does not take filenames as agruments, it expects the name of a
target, or rule, which will tell it what commands to run. From
man make:
Code:
make [OPTION]... [TARGET]...
Those
targets must be defined in a description file, or make
must be able to derive some action from existing description file rules and/or its own implicit rules. The description file is usually named Makefile, but it can have any name you care to give it.
Target rules have the general form:
Code:
target-name: [prerequisites]
[command]
Where
prerequisites is a list of
targets or filenames on which
target-name depends, and
command is a list of zero or more commands to perform to make the target. Non-empty commands must be preceded by a TAB character as the first character on the line.
Prerequisites and commands are both optional, and a target is just a name for the thing to be done, not the file from which to do it.
When we pass make the name of a file which exists and is
not the name of a target, make tries to build a suitable target,
a chain of rules, based on what it can find in the Makefile and its own implicit rules. We can use this behavior to advantage when writing our own rules, but even when we don't it succeeds often enough that we come to think it is supposed to know what to do with any file name... until it doesn't!
So it is important to understand how make attempts to handle these cases, and what to expect when it fails. All of which is found in the make info page (info make).
Code:
* Implicit Rules:: Use implicit rules to treat many files alike,
based on their file names.
...from which...
Code:
10 Using Implicit Rules
***********************
Certain standard ways of remaking target files are used very often. For
example, one customary way to make an object file is from a C source
file using the C compiler, 'cc'.
"Implicit rules" tell 'make' how to use customary techniques so that
you do not have to specify them in detail when you want to use them.
For example, there is an implicit rule for C compilation. File names
determine which implicit rules are run. For example, C compilation
typically takes a '.c' file and makes a '.o' file. So 'make' applies
the implicit rule for C compilation when it sees this combination of
file name endings.
A chain of implicit rules can apply in sequence; for example, 'make'
will remake a '.o' file from a '.y' file by way of a '.c' file.
...
And the actual algorithm used to decide how to apply implicit rules...
Code:
* Implicit Rule Search:: The precise algorithm for applying
implicit rules.
...will lead you here...
Code:
10.8 Implicit Rule Search Algorithm
===================================
Here is the procedure 'make' uses for searching for an implicit rule for
a target T. This procedure is followed for each double-colon rule with
no recipe, for each target of ordinary rules none of which have a
recipe, and for each prerequisite that is not the target of any rule.
It is also followed recursively for prerequisites that come from
implicit rules, in the search for a chain of rules.
...
Let's break that out into a list of things make looks for to work out application of its implicit rules so we can see them very clearly:
Code:
This procedure is followed for
** each double-colon rule with no recipe
** each target of ordinary rules none of which have a recipe
** each prerequisite that is not the target of any rule
** recursively for prerequisites that come from implicit rules
So, if the filename we pass as target to make is found anywhere in our Makefile as a target or as a prerequisite, make will usually figure out how to build it!
BUT - when we create a new file which does not appear anywhere in our Makefile, and pass that filename to make it will complain...
Code:
make: Nothing to be done for 'newfile.c'.
Make is telling us it could not find
any thing to do with this file either in our Makefile targets or by application of its implicit rules. And that is a good thing, otherwise make would treat it as the target and might overwrite our file!
The fix is, of course, to write a target rule which will handle the file, or include the filename in the list of prerequisites for one or more targets.
I hope this info will help provide some useful focus for those who use make only occasionally but not often enough to learn all of its tricks. Just remember, make expects
targets, things to be made and rules for making them, as its arguments and can only handle filenames as arguments when they are covered by an existing target, explicitly or implicitly.
Good luck!