LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-22-2020, 05:58 PM   #1
Johannes33
Member
 
Registered: Jul 2015
Distribution: manjaro Xfce
Posts: 80

Rep: Reputation: Disabled
make auto complete? Programmable Completion?


Hi,
Lets say that I have a directory with the file:
testfile.c.

In the same directory I have a Makefile:
Code:
CFLAGS=-Wall -g -W -pedantic -ansi -std=c99
CC=gcc
I call make with

>make te<tab>
but I get no auto completion.

If I add "testfile:" to the Makefile:
Code:
CFLAGS=-Wall -g -W -pedantic -ansi -std=c99
CC=gcc
testfile:
And I call make with:

>make te<tab>

it will generate

>make testfile

so auto complete works.

But how do I get it to work without "testfile:" in the Makefile?
 
Old 09-22-2020, 06:05 PM   #2
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,725

Rep: Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211
If te(tab) matches multiple files, it doesn’t return anything. use a second tab to get a list of those files

Also, autocomplete is searching PATH...if the current directory is not in the PATH, it won’t find testfile. Try
Code:
$ make ./te(tab)
to search in the current directory.
 
Old 09-23-2020, 08:50 AM   #3
Johannes33
Member
 
Registered: Jul 2015
Distribution: manjaro Xfce
Posts: 80

Original Poster
Rep: Reputation: Disabled
It does not work.

Make wonders what to do. We are making a new file so it asks what file I want to make and I can not auto-complete. It is logical but I would like that make is looking in wd (working directory) and seeing the files there with .c and using it as a template for auto-complete. I.e. test.c should auto-complete to make test.

bash has programmable completion. I just do not know how to do it.
I tried to read up but the sources I found goes beyond what I understand.
 
Old 09-23-2020, 09:06 AM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,799

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
the usual way is to invoke make <target> and that target is specified as <target>: at the beginning of the line.
So tab completion will look for a target in the makefile beginning with te (in your case). This is how it is designed [to work].

what you wrote/expect is something different, I think you need to implement that yourself (=override the default behavior).

make testfile will not work if you have no such target specified. You can have implicit targets, but I don't think bash auto completion can handle that.

Last edited by pan64; 09-23-2020 at 09:11 AM.
 
2 members found this post helpful.
Old 09-23-2020, 03:40 PM   #5
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
If you really want this behavior, you delete the autocompletion file for make.
 
1 members found this post helpful.
Old 09-23-2020, 05:14 PM   #6
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
@Johannes33,

Suggest you look up Makefile examples: https://cs.colby.edu/maxwell/courses...als/maketutor/

Done correctly you need no arguments, but can use them if you like. Either case, once done properly, you only will need to type "make" and it'll make your project.

That site starts with a very simple Makefile and then grows the example. I've seen that in the past because when I go to construct a Makefile, every year or so, I search for examples and that always pops up near the top of my searches.
 
1 members found this post helpful.
Old 09-23-2020, 06:42 PM   #7
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
Quote:
Originally Posted by Johannes33 View Post
so auto complete works.

But how do I get it to work without "testfile:" in the Makefile?
It works with targets that are in the Makefile because your user's shell has loaded a completion script for make, probably at login. That script only parses Makefile targets for shell completion, but not filenames.

If you want completion with filenames...

Quote:
Originally Posted by dugan View Post
If you really want this behavior, you delete the autocompletion file for make.
But you may then get a message like the following for files without a Makefile target, depending on the make default rules in force at the time...

Code:
make: Nothing to be done for testfile.c
Which is a little misleading as it implies it is up to date, but this is make's default behavior for combinations of non-existent targets with existing files.

Does yours actually compile with just the filename? Try it, I think it will produce the above message.

But what you are actually asking is a bit more complex than this:

Quote:
Originally Posted by Johannes33 View Post
I would like that make is looking in wd (working directory) and seeing the files there with .c and using it as a template for auto-complete. I.e. test.c should auto-complete to make test.
You want filename completion but truncated to the last character before the file extension. Additionally, you would probably still want the Makefile targets to be completed as well.

To get that total completion behavior you need to modify the make shell completion script to merge the Makefile targets and the truncated filename list. That should not be really difficult (based on a quick look at the make completion script on my own machine), but you would need to precisely define how you want it to work (i.e. does it follow subdirectories? ...does it only look at files with .c extension? etc...).

The best way I think would be to simply add the targets and dependencies to your Makefile as your project grows, and have the certainty that you know what the outcome of the build will be without reliance on default behaviors which can be somewhat obscure with make. That is what Makefiles are for.

Last edited by astrogeek; 09-25-2020 at 11:53 PM. Reason: Remove statement out of context
 
1 members found this post helpful.
Old 09-23-2020, 11:08 PM   #8
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
Quote:
Originally Posted by astrogeek View Post
Code:
make: Nothing to be done for testfile.c
Does yours actually compile with just the filename?
FWIW, I get "Nothing to be done for..." on Fedora 32 and OS X.

I'm curious as to what Johannes33's distro is.

Knowing the distro would also help us to help him find the file to delete.

Last edited by dugan; 09-23-2020 at 11:31 PM.
 
Old 09-24-2020, 08:42 AM   #9
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Based on a re-read, my interpretation/answer is incorrect because the question centers around getting auto-complete to work, but for a make call.

If this is academic study about how to manipulate things, then by all means, please continue. I do not believe I have much input on that particular subject.

If this is about optimizing one's typing time/effort, ...
  1. Just type it, exasperation. And sorry, but my eyes roll at the amount of time people spend making shortcuts. If you're writing code, you likely are typing a lot as it is, what's the need to shortcut a word, and especially if you do write your Makefile to have a default target which will build just using the word "make".
  2. More serious: I do not recommend having multiple targets in a make file. Options: Yes. Such as "all", "clean", and "install", but if you have multiple output targets, then it would seem to be another Makefile, or if they're all self-contained programs and many of them, then why not just build all? OK, if there are something like hundreds of targets, well ... part of that is sub-segmenting the target types into categories and having several sub-make files. And then you really do have a top level Makefile which supports arguments like: make apps, make libs, or make docs. Still, the example names are brief, and can be brief. How much TAB optimization does one need?
I'll shut my mouth here, because I realize that people do stuff, because they wish to.
 
1 members found this post helpful.
Old 09-25-2020, 03:12 AM   #10
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
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!

Last edited by astrogeek; 09-26-2020 at 01:09 AM. Reason: more precise wording, I hope
 
2 members found this post helpful.
  


Reply

Tags
bash-completion, makefile



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Bash Programmable Completion - Tutorial LXer Syndicated Linux News 0 03-01-2018 11:56 AM
[SOLVED] bash-completion: mpv does not complete orbea Slackware 1 05-08-2016 11:51 AM
bash completion "complete -f" not working iamback Linux - Software 1 05-21-2008 11:43 PM
bash: How do I disable programmable completion Ghodmode Linux - General 2 09-05-2007 12:59 AM
auto-completion - how does it work & can my script args auto-complete? BrianK Programming 1 06-11-2004 04:51 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:55 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration