1

I made the foolish decision to move my work environment to Windows 11.

I have downloaded GNU Make version 4.3 using chocolatey. Make replies when I prompt it for its version, but returns the error 'cat' is not recognized as an internal or external command, operable program or batch file. when I ask it to build my project.

I am working on Windows Powershell version 5.1.22000.1335, where I can run "$cat ExampleFile.txt" and see the expected behavior. I can even find the alias table showing that Powershell converts cat into Get-Content, but for some reason this aliasing isn't being applied to the call within the make system. Is there another command I should have Powershell alias cat to?

Has anyone resolved this sort of issue before? Thank you for reading!

6
  • Thank you for the quick reply, John, but the make system has worked on previous versions of Windows (superuser.com/questions/808807/…). I agree that a virtual machine could solve the issue but I believe that would be overkill for the problem I'm having here.
    – psyduck
    Commented Jan 11, 2023 at 15:59
  • user2048773 responded in early 2021 showing how to get it up and running on Windows 10 and Little Helper responded in late 2022 showing the solution I attempted (albeit without saying what version of Windows that was done on). I would comment to ask that user directly but my account does not have enough reputation points to do so.
    – psyduck
    Commented Jan 11, 2023 at 16:15
  • $cat is likely an internal command of powershell. this can not be accessed by gnu make. Need get 'cat' program from elsewhere, as this seems to be used by your makefile Commented Jan 11, 2023 at 16:31
  • Thank you, Joakim. I'll follow that lead and post my results.
    – psyduck
    Commented Jan 11, 2023 at 16:34
  • @Joakim Elofsson --- As for this: $cat is likely an internal command of powershell., this is not true, cat is an internal command alias for Get-Contnet`. Using this, $cat``` is a variable name that has to have an assigned value. You can get a list of all PS aliases by using Get-Alias -Name '*' | Out-Gridview.
    – postanote
    Commented Jan 11, 2023 at 20:14

2 Answers 2

1

The fact that "your project" uses cat in its build process indicate it's likely a project that targeted (originally, at least) Linux (well, or other UNIX-like OS).

In that case (or perhaps even, in any case that isn't a VS project?), you probably need a full toolchain et. al. (well, e.g. cat) anyway, and msys2 is probably one of the choices you want to consider. It provides different shells that are set up to allow the building of either native Windows (mingw) builds or msys2 builds (which rely on a POSIX compatibility layer / library that msys2 provides) of a program.

Note that whether you can build your the program as the former depends on the portability of the program itself.


w64devkit and WinLibs are alternatives that might interest you. (Not sure if you'll get any cat with the latter though.)


GNU Make is really just a program that processes Makefiles. Whether it is sufficient for your "project" depends on what exactly will be run (directly or indirectly) as the Makefile instructed.

cat is part of GNU coreutils. (Well, there are different implementations of cat I suppose; for example you also get a cat from busybox.) I'm not sure if it is possible to build native build of it for Windows anymore. Apparently there's an ancient port though, which you can get with chocolatey as well. (Another option could be this.)

1

As for this,

"$cat ExampleFile.txt"

$cat or "$cat" specified this way is a variable.

"$cat D:\temp\TestFile.txt"
# Results
<#
 "$cat D:\temp\TestFile.txt"
The variable '$cat' cannot be retrieved because it has not been set.
At line:1 char:2
+ "$cat D:\temp\TestFile.txt"
+  ~~~~
    + CategoryInfo          : InvalidOperation: (cat:String) [], RuntimeException
    + FullyQualifiedErrorId : VariableIsUndefined
#> 

PS will evaluate that to whatever is the value/data in the $cat variable, not run the cat command.

See the available info on PowerShell variable expansion.

https://devblogs.microsoft.com/powershell/variable-expansion-in-strings-and-here-strings/

As noted cat is an alias for Get-Content, and it must be used that way.

For the command to work, you must do it this way.

cat 'D:\temp\TestFile.txt'
# Results
<#
1   21/05/20
2   21/05/20
3   21/05/20
4   21/05/20
5   21/05/20
6   21/05/20
7   21/05/20
8   21/05/20
#>

Unless you did this...

$cat = cat

... somewhere else in your code. Meaning you assigned a command to a variable name. Which, especially for a single comment is not really prudent.

If you tried that in this use case, it would still fail.

$cat = cat
"$cat D:\temp\TestFile.txt"
# Results
<#
 $cat = cat
"$cat D:\temp\TestFile.txt"
cmdlet Get-Content at command pipeline position 1
Supply values for the following parameters:
Path[0]:
#>

To get that variable stuff to work in the above, you have to declare it either as a function or a ScriptBlock. IMHO just overcomplicating things for something the direct if you did.

# using a ScriptBlock
$cat = {cat $($args[0])}
& $cat 'D:\temp\TestFile.txt'
# Results
<#
1   21/05/20
2   21/05/20
3   21/05/20
4   21/05/20
5   21/05/20
6   21/05/20
7   21/05/20
8   21/05/20
#>

about_Script_Blocks

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_script_blocks?view=powershell-7.3

Lastly for any external command to be discoverable, it must be in your system and PS paths.

See also PS command precedence

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_command_precedence?view=powershell-7.3

PowerShell- Running Executables - TechNet Articles - United States (English) - TechNet Wiki

https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .