A hash inside a Makefile call invokes unexpected behavior

The following command prints the absolute path for a specific C ++ header, according to how g ++ considers this.

echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-: //' -e 's/ \\//' 

On my system, these outputs are: /usr/local/include/ham/hamsterdb.hpp

I ran into a problem while trying to run this inside a Makefile to set a variable:

 FILE=$(shell echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-: //' -e 's/ \\//') .PHONY spec spec: @echo $(FILE) 

This prints a new line. I think this is a hash ('#') character that messes with make; if I rewrote the string FILE=... as follows:

 FILE=$(shell echo \#include\<ham/hamsterdb.h\>) 

the conclusion is still nothing.

+6
source share
2 answers

You need to avoid the hash twice in order to use it inside the functions: once for Make and once again for the shell.

I.e

 FILE = $(shell echo \\\#include\ \<ham/hamsterdb.h\>) 

Pay attention to three backslashes instead of two, as you might expect. A third backslash is necessary because otherwise the first will avoid the second, and the hash will still not be saved.

UPD

Another possible solution is to avoid only the hash for Make and use single Bash quotes to prevent the hash from being interpreted as a shell comment. It also eliminates the need to escape spaces, < and > :

 FILE = $(shell echo '\#include <ham/hamsterdb.h>') 
+9
source

You only need a little more:

 FILE=$(shell echo \\\#include\<ham/hamsterdb.h\> ... ^^^ 

Quote once for make itself, second time for shell (the shell needs to "see" \# ).

+1
source

Source: https://habr.com/ru/post/907144/


All Articles