Makefile error in Protobuf 2.6.0 (Windows 10 Mingw) - makefile

I tried to install Protobuf 2.6.0 on Windows, with Mingw.
The command ./configure worked, it provided me a Makefile, but when I use the command mingw32-make to run the Makefile I have this error:
C:\Users\taka\gz-ws\protobuf-2.6.0> mingw32-make
! était inattendu. //translation: "! was not expected"
Makefile:558: recipe for target 'config.h' failed
mingw32-make: *** [config.h] Error 255
The line 558 of the Makefile:
config.h: stamp-h1
#if test ! -f $#; then rm -f stamp-h1; else :; fi
#if test ! -f $#; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi`
I don't know what to do here.

I found the solution. You need to use Msys and not MinGW, be cause MinGW doesn't have access to all Unix Bash. (run make and not mingw32-make)
So it cannot recognize the line 558 but Msys can read it correctly.

Related

How to use shell command in GNU Make to echo string

I have the following lines in my makefile:
.PHONY : clean
clean:
#echo "Running Clean"
$(shell if [ -e exe ]; then rm exe; else echo "no files"; fi)
When I run:
make clean
I get the following output on the shell
Running Clean
no files
make: no: Command not found
Makefile:22: recipe for target 'clean' failed
make: *** [clean] Error 127
Any suggestions?
The problem is the use of $(shell ...). What you want is:
.PHONY : clean
clean:
#echo "Running Clean"
#if [ -e exe ]; then rm exe; else echo "no files"; fi
As far as an explanation of what's going wrong -- when you first run the clean target, make will expand all make variables and functions in the recipes before it starts running them -- because $(shell ...) only has one $, this is considered a make function. Make runs the command, which outputs no files to stdout, and replaces the call with that string, and then starts executing the recipes... So now make sees the following:
clean:
#echo "Running Clean"
no files
When it tries to run no files, due to the lack of a #, it echos the line to the screen, and then passes the command to the shell. Because the shell doesn't recognize the keyword no it outputs the error you're seeing. Make itself then fails because the shell returned an error.
Hey all I'm the same guy who asked this question but I found an answer right after I posted this, I think I'll leave this up (unless this is against stackoverflow etiquette) in case someone else has the same problems. My solution was echoing the string to stdout.
$(shell if [ -e exe ]; then rm exe; else echo "no files" >&2; fi)

Shell Commands Using ( on Makefile

I'm preparing some latex files and decided to make some makefile to help me to compile and clean de latex files. So I created the following makefile
aula=listaProb
all: compile clean
compile:
pdflatex $(aula).tex
clean:
rm -rf !(makefile|$(aula).tex|$(aula).pdf) -v
But when I execute "make" I get the following mistake
rm -rf !(makefile|listaProb.tex|listaProb.pdf) -v
/bin/sh: 1: Syntax error: "(" unexpected
makefile:8: recipe for target 'clean' failed
make: *** [clean] Error 2
But the command
rm -rf !(makefile|listaProb.tex|listaProb.pdf) -v
works fine on the terminal.
What is wrong? I can't find any mistake :/..
Ps. I use this way to remove the files because I want to delete all but the specified files. It needs the command
shopt -s extglob
before use it. If anyone knows how to do it without use extglob, it would be nice.
Thanks
The problem is recipe commands are passed to /bin/sh which cannot process that syntax. You can change your Makefile to say:
clean:
bash -O extglob -c "rm -rf !(makefile|$(aula).tex|$(aula).pdf) -v"
To force this command to be run in bash with extglob on.
Or define SHELL variable for your make e.g. by running:
make SHELL="/bin/bash -O extglob" clean
Or adding:
SHELL := /bin/bash -O extglob
To your make file. The former option only affects shell invocation of that one command, the latter will apply to all your recipes (commands).

GNU Make: "dir not expected at this moment"

I have a makefile including the following lines:
buildrepo:
#$(call make-repo)
define make-repo
for dir in $(C_SRCS_DIR); \
do \
mkdir -p $(OBJDIR)/$$dir; \
done
endef
On the line with the commands for dir in $(C_SRCS_DIR); \ I get the following error message:
"dir not expected at this moment"
make: *** [buildrepo] Error 255
I am using GNU make.
Can anybody tell me what is going wrong?
Actually this for ... in ... ; do ... done statement is a Unix command not a GNU make command, therefore I guess you are using a Windows machine (or any other one). You have to find the equivalent for your system.
But GNU make has a foreach function which works like this :
$(foreach dir,$(C_SRCS_DIR),mkdir -p $(OBJDIR)/$(dir);)
Also note that in your very specific case (not related to GNU make but to Windows) you can create all the dirs without a for/foreach loop, just like this :
mkdir -p $(addprefix $(OBJDIR)/,$(C_SRCS_DIR))

Makefile - how to differentiate between a variable assignment and a command

I have the following code in my Makefile, but I get the error mentioning that O?=2 is not a command that sh -c can run. What am I doing wrong here?
gcc:
O?=2
#if test -z "$(DEBUG)" ; then \
g++ -O${O} *.c -o palindrome ; \
fi
I am trying to set O to 2 if the user did not provide it, and then build my palindrome executable.
Exact error:
$ make gcc
O?=2
/bin/sh: O?=2: command not found
make: *** [gcc] Error 127
$
Move it outside the command, so that it gets processed by "make" instead of the shell:
O?=2
gcc:
#if test -z "$(DEBUG)" ; then \
g++ -O${O} *.c -o palindrome ; \
fi
The line O?=2 is not an assignment, but a command executed to rebuild target gcc. This means it is fed to $(SHELL), which doesn't know a thing about it. If you want a variable assingment, put it on line by itself and not as a part of commands:
O?=2
gcc:
#if test -z "$(DEBUG)" ; then \
g++ -O${O} *.c -o palindrome ; \
fi
You can just use O = 2. When the user provides a value on the command line it will override it:
make O=1
will use -O1 for optimization.

Makefile for Daemon

I am very new to Makefiles, so I am probably not doing this the best way (your input is much appreciated, since I would like to learn how/why mine is bad). Anyway, here is my problem:
I have a Daemon that I wrote for a program of mine and I am trying to install it with the Makefile (target is "install"). What the "install" target is supposed to do is move the daemon binary to a location, then move the "service script" to either /etc/init.d/ or /etc/rc.d/ (since different distros have different folders...). Here is my makefile so far:
all:
#echo "Making Components"
#cd Daemon; make
#echo "Components Built"
install:
#echo "Installing Components"
#mkdir -p /usr/lib/
#cp Daemon/myprog_d /usr/lib/myprog_d
-#test -d /etc/init.d && cp Scripts/myprog /etc/init.d/
-#test -d /etc/rc.d && cp Scripts/myprog /etc/rc.d/
-#test ! -d /etc/init.d -a ! -d /etc/rc.d && echo " Warning: Couldn't install script. Manually install Scripts/myprog"
#mkdir -p /var/log/
#echo "Installed."
uninstall:
#echo "Uninstalling Components"
#./Scripts/myprog stop > /dev/null
#rm -f /usr/lib/myprog_d
#echo "Uninstall complete"
clean:
#echo "Cleaning Components"
#cd Daemon; make clean
#echo "Clean complete"
As you can see, the "install" target tests to see if those two directories exist and, if they do, copies the script into them (I haven't yet done it to "uninstall", don't worry).
My first question: Is this the right way to do this? The "all" and "clean" targets work (there is another makefile in "Daemon/", as you can deduce), but I want to know if there is a cleaner way of doing this.
Secondly, because the "test" function returns non-zero, I had to do "-" before it so the error would be ignored. Unfortunately, that results in the "make install" output being:
Installing Components
make: [install] Error 1 (ignored)
make: [install] Error 1 (ignored)
Installed.
Which is very ugly and probably not good practice. What can I do in this case? (I have tried both -# and #-, but # will not suppress the "ignored" output)
Sincerely,
Chris
I'd do it this way:
#if [ -d /etc/init.d ]; then cp Scripts/myprog /etc/init.d/ ; fi
#if [ -d /etc/rc.d ]; then cp Scripts/myprog /etc/rc.d/ ; fi
And I'm a little confused by your next line (-#test ! -d /etc/init.d -a !...) but you can probably do it the same way.
That takes care of the error messages, but if you wanted to keep the makefile as it is, you could suppress them by running make -s.

Resources