Skip to content

fix(make): exclude .NOTINTERMEDIATE from target completion - #1715

Open
15daksh-2003 wants to merge 1 commit into
scop:mainfrom
15daksh-2003:fix-make-special-targets
Open

fix(make): exclude .NOTINTERMEDIATE from target completion#1715
15daksh-2003 wants to merge 1 commit into
scop:mainfrom
15daksh-2003:fix-make-special-targets

Conversation

@15daksh-2003

Copy link
Copy Markdown
Contributor

.NOTINTERMEDIATE (a GNU make 4.4 special target) was missing from the
extractor's special-target skip list, so it leaked into completion on a
dotted prefix like make .NOT<TAB> — a make directive, not a runnable
target. The hidden-target guard only suppresses dotted names on an empty
or trailing-/ prefix, so the explicit list is the sole filter for
specials under a dotted partial prefix.

Fix: add .NOTINTERMEDIATE to the list — a one-line, additive change,
with a regression test/fixture. .WAIT and .EXTRA_PREREQS are
deliberately not added: .WAIT is a parse-consumed prerequisite marker
and .EXTRA_PREREQS is a variable, so neither surfaces as a target block.

Follow-up from the #1693 review.

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

@akinomyoga here for engagement on this

@akinomyoga akinomyoga left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.WAIT is a parse-consumed prerequisite marker

The GNU make manual says

You can create an actual target .WAIT in your makefile for portability but this is not required to use this feature. If a .WAIT target is created it should not have prerequisites or commands.

It seems to imply that .WAIT may be listed by older versions of GNU make when the user adds the prerequisite .WAIT to work around the "unknown target" error in the older versions of GNU make. I also confirmed that, even in the newer versions of GNU make, when the .WAIT prerequisite is present in Makefile/GNUmakefile, .WAIT is listed in make -npq. I believe those workaround prerequisites .WAIT should be excluded anyway.

@15daksh-2003
15daksh-2003 force-pushed the fix-make-special-targets branch from 955ca98 to ed837fd Compare August 5, 2026 05:54
@15daksh-2003

Copy link
Copy Markdown
Contributor Author

The GNU make manual says

You can create an actual target .WAIT in your makefile for portability but this is not required to use this feature. If a .WAIT target is created it should not have prerequisites or commands.

It seems to imply that .WAIT may be listed by older versions of GNU make when the user adds the prerequisite .WAIT to work around the "unknown target" error in the older versions of GNU make. I also confirmed that, even in the newer versions of GNU make, when the .WAIT prerequisite is present in Makefile/GNUmakefile, .WAIT is listed in make -npq. I believe those workaround prerequisites .WAIT should be excluded anyway.

makes sense. included it

@akinomyoga

Copy link
Copy Markdown
Collaborator

For the existing if (/^\.MAKE:/ ) next;, GNU make doesn't seem to recognize .MAKE (or at least it doesn't describe it in its manual). The .MAKE seems to be a special target written for BSD make, but BSD make seems to have more special sources and targets. Should we also include these for consistency?

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

For the existing if (/^\.MAKE:/ ) next;, GNU make doesn't seem to recognize .MAKE (or at least it doesn't describe it in its manual). The .MAKE seems to be a special target written for BSD make, but BSD make seems to have more special sources and targets. Should we also include these for consistency?

even before that I found something interesting: the manual's --print-targets section says it excludes "special targets (target names consisting of . followed by all upper-case letters)."...makes me think why do we need to define the special targets all explicitly. why not pattern based approach here? This needs a bit of thinking I think for nuances.

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

as for the BSD make special targets...I was checking if there is any rationale behind why and how .MAKE and so got introduced in the project for special targets. This seems to have been added in 2012...not sure if while adding this there was a GNU specific rationale...

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

but yeah...print targets or so itself would land in 4.5....

@15daksh-2003

15daksh-2003 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

even before that I found something interesting: the manual's --print-targets section says it excludes "special targets (target names consisting of . followed by all upper-case letters)."...makes me think why do we need to define the special targets all explicitly. why not pattern based approach here? This needs a bit of thinking I think for nuances.

from the code, it seems the awk runs in the user locale. for something like a pattern, awk [A-Z] is a collation range (can match lowercase in case-interleaving locales → silently drop a real target). one good analogue could be [[:upper:]]

also from what make's defined approach for print_targets is....it does not seem to take into account specials with underscores like .DELETE_ON_ERROR, .LOW_RESOLUTION_TIME, .EXPORT_ALL_VARIABLES.... something that ^.[A-Z]+$ won't match

@15daksh-2003

15daksh-2003 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

as for the BSD make special targets...I was checking if there is any rationale behind why and how .MAKE and so got introduced in the project for special targets. This seems to have been added in 2012...not sure if while adding this there was a GNU specific rationale...

For the existing if (/^\.MAKE:/ ) next;, GNU make doesn't seem to recognize .MAKE (or at least it doesn't describe it in its manual). The .MAKE seems to be a special target written for BSD make, but BSD make seems to have more special sources and targets. Should we also include these for consistency?

also, while checking on this further....NOEXPORT also seems obsolete and redundant sort of... from I think 4.9 section of manual. further BSD -p seems to have a different shape altogether, whereas our parser seems to be catering to GNU only. Extending...might be a rabbit hole .....

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

even before that I found something interesting: the manual's --print-targets section says it excludes "special targets (target names consisting of . followed by all upper-case letters)."...makes me think why do we need to define the special targets all explicitly. why not pattern based approach here? This needs a bit of thinking I think for nuances.

from the code, it seems the awk runs in the user locale. for something like a pattern, awk [A-Z] is a collation range (can match lowercase in case-interleaving locales → silently drop a real target). one good analogue could be [[:upper:]]

also from what make's defined approach for print_targets is....it does not seem to take into account specials with underscores like .DELETE_ON_ERROR, .LOW_RESOLUTION_TIME, .EXPORT_ALL_VARIABLES.... something that ^.[A-Z]+$ won't match

I got the code snippet as this:

static void
print_target (const void *item)
{
  const struct file *f = item;

  if (!f->is_target || f->suffix)
    return;

  /* Ignore any special targets, as defined by POSIX. */
  if (f->name[0] == '.' && isupper ((unsigned char)f->name[1]))
    {
      const char *cp = f->name + 1;
      while (*(++cp) != '\0')
        if (!isupper ((unsigned char)*cp))
          break;
      if (*cp == '\0')
        return;
    }

  puts (f->name);
}

void
print_targets (void)
{
  hash_map (&files, print_target);
}

@15daksh-2003

15daksh-2003 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

@akinomyoga for thoughts on these thingy. mostly because of underscore specials...I think staying on list only is good for now

@akinomyoga akinomyoga left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, Makefile can be designed to be compatible with both GNU and BSD variants of make. Such a Makefile may contain the targets that have meanings in a make implementation and are ignored in the other make implementions. In principle, those targets should be excluded regardless of whether GNU make interprets it as a special target. However, although I'm not sure why only .MAKE from BSD make was excluded in the present script, I think we don't have to care about BSD special targets too much.

The character range of A-Z is not a relevant issue because we can set LC_COLLATE=C to take care of it.

The target .NOEXPORT seems to have been supported by very old versions of GNU make, and autotools (which is known to be excessively backward compatible) seems to still generate such a target. Then, it is reasonable to continue supporting exclusion of it.

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

In general, Makefile can be designed to be compatible with both GNU and BSD variants of make. Such a Makefile may contain the targets that have meanings in a make implementation and are ignored in the other make implementions. In principle, those targets should be excluded regardless of whether GNU make interprets it as a special target. However, although I'm not sure why only .MAKE from BSD make was excluded in the present script, I think we don't have to care about BSD special targets too much.

makes sense

The character range of A-Z is not a relevant issue because we can set LC_COLLATE=C to take care of it.

since we r going with list, i think this only comes into picture for pattern based approach..we can drop thinking on this

The target .NOEXPORT seems to have been supported by very old versions of GNU make, and autotools (which is known to be excessively backward compatible) seems to still generate such a target. Then, it is reasonable to continue supporting exclusion of it.

makes sense

@15daksh-2003

Copy link
Copy Markdown
Contributor Author

@akinomyoga should we merge this?

@akinomyoga

Copy link
Copy Markdown
Collaborator

I would like input from another maintainer.

@yedayak yedayak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me

Comment thread test/t/test_make.py Outdated
@15daksh-2003
15daksh-2003 force-pushed the fix-make-special-targets branch from ed837fd to 774e5d6 Compare August 12, 2026 17:14
`.NOTINTERMEDIATE' (GNU make 4.4) and `.WAIT' are special targets that
were missing from the extractor's skip list, so they leaked into
completion on a dotted prefix (`make .NOT<TAB>' / `make .WA<TAB>').
`.WAIT' surfaces as a real target block via its documented empty-target
portability form. Add both, with regression tests.

Follow-up from the scop#1693 review.
@15daksh-2003
15daksh-2003 force-pushed the fix-make-special-targets branch from 774e5d6 to a7e8cf9 Compare August 13, 2026 16:37
akinomyoga added a commit to akinomyoga/bash-completion that referenced this pull request Aug 13, 2026
In "test/t/{test_make.py,unit/test_compgen_filedir_xspec.py}", the
plain "completion = assert_complete(...)" can be replaced with
"@pytest.mark.complete" markers.

For "test/t/unit/test_unit_compgen_{commands,filedir}.py", the
"class"-scope fixture "functions" are ensured to be initialized before
the "function"-scope fixture "completion", so we can use "completion"
even when the test relies on "functions".

[1] scop#1715 (comment)
scop pushed a commit that referenced this pull request Aug 13, 2026
In "test/t/{test_make.py,unit/test_compgen_filedir_xspec.py}", the
plain "completion = assert_complete(...)" can be replaced with
"@pytest.mark.complete" markers.

For "test/t/unit/test_unit_compgen_{commands,filedir}.py", the
"class"-scope fixture "functions" are ensured to be initialized before
the "function"-scope fixture "completion", so we can use "completion"
even when the test relies on "functions".

[1] #1715 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants