MacOS catalina Makefile not processing shell commands correctly that work in CLI

1.4k Views Asked by At

TL;DR:

This does not work in a Makefile in MacOS (catalina):

grab_setup_rule != cat $(all_makefiles_except_current)  | grep -h -E '.+-setup:.*##' | awk '{ print $1 }'

but on executed on the command line, with $(all_makefiles_except_current) replaced with the correct paths, it works.


In depth explanation

Hey,

I have the following code in a Makefile:

BASEPATH = ..
repos = project1 project2
possible_includes = $(foreach repo,$(repos), $(BASEPATH)/$(repo)/Makefile)

-include $(possible_includes)

all_makefiles_except_current := $(wordlist 2,$(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
grab_setup_rule != cat $(all_makefiles_except_current)  | grep -h -E '.+-setup:.*##' | awk '{ print $1 }'

What this does is include all the Makefiles specified in the repos variable, get a list of all included files, set in all_makefiles_except_current, and then try to grab all the targets from those Makefiles that end with -setup.

This is an example of what is in the included Makefiles:

projectName-targetX: ### desc
    code

projectName-setup: ## desc
    code

<.. more targets ..>

This is a self-documenting makefile.

If I run the shell commands:

cat ../project1/Makefile | grep -h -E '.+-setup:.*##' | awk '{ print $1 }'

NOTE: on windows and linux the grep regex has to be without single quotes, ex.: grep -h -E .+-setup:.*##

on the command line, IT WORKS, I get the targets that I want and this will work on Windows (msys2), on Linux (ubuntu) and on MacOS (catalina).

But on the Makefile the grab_setup_rule will always be empty in MacOS. Seems it doesn't get processed correctly.

What am I doing wrong in the grab_setup_rule on MacOS?

1

There are 1 best solutions below

3
On BEST ANSWER

The != operator was added in GNU make 4.0. It is not available in older releases.

Apple is scared of the GPLv3 license and refuses to ship any GNU software using that license, so they will never provide a version of GNU make newer than 3.81 (released in 2006). They have similarly old and broken versions of other GNU software including their standard interactive shell, bash.

You can either download the GNU make source code and build it yourself, or use brew or similar to get a newer version, or else use the := $(shell ...) method of invoking a shell command and assigning it to a variable which works in GNU make 3.81 as well.