Unterminated quoted string : bin/sh - bash

I have the following makefile:-
all:
find | grep -E "\.c\$" | xargs gcc -c -I src -I include -w
gcc -o main *.o -lm -pthread
On running make I get the following error:-
find | grep -E "\.c\ | xargs gcc -c -I src -I include -w
/bin/sh: 1: Syntax error: Unterminated quoted string
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 2
I tried answers to similar questions, but adding a SHEBANG line did not help. Also, I have already escaped the $ character. What am I doing wrong here?

make already does most of what you are trying to do. Assuming you aren't expecting find to look recursively in subdirectories, all you really need is
# Rule for building a c file
.c:
gcc -c -I src -I include -w -o $# $<
# Make sure all C files are compiled, then link the resulting object files
all: *.c
gcc -o main *.o -lm -pthread
If you were expecting to find C source files in subdirectories, you might want to restructure your project slightly, by adding Makefiles to each subdirectory and calling make recursively in those directories.

Related

Simple makefile command not found

I was given a makefile that looks like this, and told not to change it.
all: clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp clean: rm -f lex.yy.c rm -f parser.tab.*pp rm -f hw2
I am trying to run this makefile in a folder with files named: scanner.lex, parser.ypp, output.hpp and output.cpp
I copied it to a file like this:
all:
clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp
clean:
rm -f lex.yy.c rm -f parser.tab.*pp rm -f hw2
When I run the make command in my terminal I get an error:
clean flex scanner.lex bison -d parser.ypp g++ -std=c++11 -o hw2 *.c *.cpp
/bin/sh: clean: command not found
make: *** [all] Error 127
Am I doing something wrong? Again, I was given this line and told not to change it.
Thanks a lot.
Line breaks are essential in most computer environments. If you were given a Makefile without the line breaks and you try to cut it randomly you will have difficulties before if finally works. Try this, maybe:
all: clean
flex scanner.lex
bison -d parser.ypp
g++ -std=c++11 -o hw2 *.c *.cpp
clean:
rm -f lex.yy.c
rm -f parser.tab.*pp
rm -f hw2
And use tabs to indent the indented lines, not spaces.
Explanations: all and clean are what is called a target in make parlance. They are the names of the things you want make to do. clean to delete some files, all to do everything else. The
target: prerequisite1 prerequisite2...
recipe1
recipe2
...
template is the basic make template. It means that target depends on prerequisite1, prerequisite2 and that in order to build it make shall pass recipe1 to the shell for execution, then recipe2...
Note that this Makefile is poorly written. As all and clean are not real file names they should be declared as phony, such that, if a file with that name exists make does the job anyway. As is, it wouldn't. Give it a try:
$ make all
$ touch clean
$ make clean
make: 'clean' is up to date.
See? Because a file named clean exists you cannot make clean anymore, make considers that there is nothing to do for clean. Add this at the beginning of your Makefile:
.PHONY: all clean
A second issue is that make works by comparing last modification times of targets and prerequisites to decide if targets must be rebuilt or not. With your Makefile make will always recompile everything, even if the inputs did not change and the outputs are up-to-date. This is a waste. A better (but untested) Makefile would be something like:
.PHONY: all clean
CFILES := $(filter-out lex.yy.c,$(wildcard *.c))
CPPFILES := $(filter-out parser.tab.cpp,$(wildcard *.cpp))
all: hw2
hw2: lex.yy.c parser.tab.cpp $(CFILES) $(CPPFILES)
g++ -std=c++11 -o $# $^
lex.yy.c: scanner.lex
flex $<
parser.tab.cpp: parser.ypp
bison -d $<
clean:
rm -f lex.yy.c
rm -f parser.tab.*pp
rm -f hw2
Understanding it and why it is better is left as an exercise.

Building zookeeper 3.4.12 c client on solaris machine fails with libtool error

I am trying to build zookeeper 3.4.12 c client on the Solaris machine. Below are the steps that I followed,
unzip/untar the source tarball and cd to the zookeeper-x.x.x/src/c
directory.
Do a "./configure [OPTIONS]" to generate the makefile.
./configure --without-cppunit
This step fails with below error,
/bin/sh ./libtool --tag=CC --mode=link gcc -Wall -Werror -g -O2
-D_GNU_SOURCE -no-undefined -version-info 2 -lnsl -lsocket -export-symbols-regex '(zoo_|zookeeper_|zhandle|Z|format_log_message|log_message|logLevel|deallocate_|allocate_|zerror|is_unrecoverable)'
-o libzookeeper_st.la -rpath /usr/local/lib libzkst.la libhashtable.la libtool: link: /bin/nm -p ./.libs/libzkst.a ./.libs/libhashtable.a | | /bin/gsed 's/.* //' | sort | uniq > .libs/libzookeeper_st.exp ./libtool[1732]: eval: syntax error at line 1: `|' unexpected
*** Error code 3 make: Fatal error: Command failed for target `libzookeeper_st.la'
Any idea on the error?
Regards,
Ashwini.
The error is because you're missing a command in this portion of the command line:
... ./.libs/libzkst.a ./.libs/libhashtable.a | | /bin/gsed 's/.* //' ...
If you can find that recipe in the Makefile, there's probably a $(something) there that's expanded to an empty string, thus attempting a null command in the pipeline.
Found the issue. There was something like this in make file :
"libzookeeper_st.la: $(libzookeeper_st_la_OBJECTS) $(libzookeeper_st_la_DEPENDENCIES) $(AM_V_CCLD)$(libzookeeper_st_la_LINK) -rpath $(libdir)".
Where in if I remove -rpath $(libdir) everything builds properly.
Dont know what -rpath $(libdir) does. -rpath $(libdir) expands to "-rpath /usr/local/lib". But this resolves the issue.

Makefile not finding the include file

I Have a folder structure like this.
Gif_Utility
-> Makefile
-> include ( all .h files are over here)
-> Src ( all .c files are over here).
I am writing a makefile.
Makefile
VPATH = src:include
INC = -I ./include
gif_objects = gif_display.o \
gif_lzw.o \
gif_read.o \
sysm.o \
x86_main.o
gif_display.0 : gif_display.c
gcc -I /export/home/joshis1/MakeTutorial/GIF_Utility/include -c $<
#gif_lzw.0 : gif_lzw.c
# gcc $(INC) -c src/gif_lzw.c
#gif_read.0 : gif_read.c
# gcc -I ./include/ -c $<
#sysm_main.0 : sysm_main.c
# gcc -I ./include/ -c $<
#x86_main.0 : x86_main.c
# gcc -I ./include/ -c $<
On command prompt:
$ make gif_display.o
cc -c -o gif_display.o src/gif_display.c
src/gif_display.c:2:17: fatal error: sysm.h: No such file or directory
compilation terminated.
make: *** [gif_display.o] Error 1
On the other hand, If i do like this it compiles fine
$make
-> this creates the gif_display.o
I don't know why it is throwing error on specifying the rule. Am I missing something, please help.
I am using Ubuntu machine to build my code.
Your makefile has a .0 (zero) suffix instead of the correct .o (letter oh).
When you run just make it attempts to build the first target in the Makefile, and so runs the recipe which contains the correct -I include path. The fact that it produces an .o file, not a .0 file, is acceptable to make, although I suppose it could at least print a warning in this scenario.
When you run make gif_display.o it uses Make's built-in productions for .o files, which do not contain your include path.
Given that make already has built-in rules for .o files, your rules are basically superfluous. It would be better to just add the -I include parameter to the default rules, with something like
CFLAGS += -I include
So the entire Makefile could be as simple as this:
VPATH = src:include
CFLAGS += -I ./include
gif_objects = gif_display.o \
gif_lzw.o \
gif_read.o \
sysm.o \
x86_main.o
I don't see anything to alert your Makefile to changes in .h files, so you might want to add a separate dependency for that. If you just have a few shared header files between all your object files, maybe this will be all you need:
$(gif_objects): $(wildcard include/*.h)
This basically makes the include component of the VPATH superfluous.

Compilation errors with Make File creation

While running my make file which is as follows,
../bin/output : ../lib/libfun.a ../obj/main.o
gcc ../main.o -L ../lib/ -lfun -o $#
../lib/libfun.a : ../obj/file_write.o ../obj/error.o
ar -rc $# $^
../obj/main.o : ../src/main.c
gcc -c $^ -o $# -I ../include
../obj/file_write.o : ../src/file_write.c
gcc -c $^ -o $# -I ../include
../obj/error.o : ../src/error.c
gcc -c $^ -o $# -I ../include
I am getting error like
make: Warning: File `makefile' has modification time 2.2e+03 s in the future
ar -rc ../lib/libfun.a ../obj/file_write.o ../obj/error.o
ar: ../lib/libfun.a: No such file or directory
make: *** [../lib/libfun.a] Error 1
and sometimes
"* missing separator (did you mean TAB instead of 8 spaces?). Stop"
Why is this happening? I gave correct Target,Pre-Requests and Command values whichever needed. Whats wrong in this?
For the first error, make sure the ../lib directory exists before trying to create a library in it. ar will return that error if the path doesn't exist.
For the second make syntax is strict: the commands after a target must be indented with a tab, not spaces.
target: deps
command
# ^ this here needs to be a tab character, not spaces

GNU make not recognizing %

I'm trying to make a makefile for compiling various examples that are within a subfolder. The makefile consisting of just:
S_1_2.exe : Twister.cpp Parsing.cpp ./Surfaces/S_1_2.cpp
g++ -o $#.exe $^ -I . -W -Wall
Works fine when run with the command "make S_1_2.exe". However:
%S_1_2.exe : Twister.cpp Parsing.cpp ./Surfaces/S_1_2.cpp
g++ -o $#.exe $^ -I . -W -Wall
fails, even when run with the command make S_1_2.exe, with the error "make: * No rule to make target 'S_1_2.exe'. Stop."
Shouldn't %S_1_2.exe do pattern matching and so match S_1_2.exe? In which case why is it not matching this rule?
I am using GNU Make 3.81
The percentage symbol matches a non-empty string. So you should use %_1_2.exe or better yet - %.exe. I don't know if there is any other symbol that matches empty strings too.
The % is for matching a part of the target against the same part in one or more dependencies.
You can't omit it from all dependencies.

Resources