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!

psyduck
  • 11

2 Answers2

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.)

Tom Yan
  • 10,996
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

postanote
  • 5,136