make: Error in ifneq: word unexpected (expecting ")") - makefile

I would like to create a makefile for LaTeX documents (in this minimal
example). When there is no file "makeindexstyle.ist", it should be created (by
running make makeindexstyle.ist) and used for formatting the index. The rule for
%.pdf reflects this. However, it is not working yet, I receive the error
ifneq (, ) {
/bin/sh: 1: Syntax error: word unexpected (expecting ")")
make: *** [master.pdf] Error 2
What's wrong?
Parts from Makefile:
MASTER = master
TEX = slave
TEXI = texi2dvi -p
all: $(MASTER:=.pdf)
%.pdf: %.tex $(TEX:=.tex)
ifneq ($(wildcard makeindexstyle.ist), ) { # if makeindexstyle.ist exists, compile and build index
$(TEXI) $<
make makeindexstyle.ist
makeindex -c -s makeindexstyle.ist $(MASTER:=.idx)
}
endif
$(TEXI) $<
makeindexstyle.ist:
#(echo "...") > makeindexstyle.ist
UPDATE:
I tried to make it as simple as possible to see where the error comes from. Among other things (like quoting), I tried this:
%.pdf: %.tex $(TEX:=.tex)
exist := $(wildcard "absolute-path-to-makeindexstyle.ist")
ifneq ($strip $(exist)),)
echo "foo"
endif
$(TEXI) $<
but the result is
exists :=
make: exists: Command not found
make: *** [book.pdf] Error 127

In the meanwhile, I could solve it on the shell side:
IDX = "makeindexstyle.ist"
%.pdf: %.tex $(TEX:=.tex)
#if test -f $(IDX); then \
echo "foo"; \
fi
$(TEXI) $<

This sounds like a duplicate of How do I check if file exists in Makefile? or How to conditional set up a Makefile variable by testing if a file exists.
Try
ifneq ($(wildcard makeindexstyle.ist),)
without the space. Alternatively, throw "" around the arguments?

Related

Trying to echo a variable in a makefile but getting "missing separator"

I would like to print the variable K_INCLUDE in a make file. This is probably very simple but the examples I'm finding online are giving an error.
Here's some of the code:
#Include flags
HEADER_INCLUDE = ../include
ifeq ($(SYSTEM_TYPE), Linux)
K_INCLUDE = /bla2
endif
ifeq ($(SYSTEM_TYPE), Darwin)
K_INCLUDE = /bla
endif
GLOBAL_INCLUDE = -I$(HEADER_INCLUDE) -I$(K_INCLUDE)
# The below line gives the error
echo "k_include: $K_INCLUDE"
Produces the error:
make.include:28: *** missing separator. Stop.
make: *** [clean] Error 2

if condition in a function - Makefile

I'm working with makefile and the very simple things like if-conditions are not straight forward. it gives me an error that is not readable.
Any idea what's wrong with my following small function?
prepare-test-example:
ifeq ($(ENGINE),'aurora-postgresql')
#cat examples/example.yaml > /tmp/stack_test.yaml
else
#cat examples/example.yaml examples/example_test.yaml > /tmp/stack_test.yaml
endif
The call:
make test ENGINE=aurora-postgresql
/Library/Developer/CommandLineTools/usr/bin/make prepare-test-example ENGINE=aurora-postgresql
ifeq (aurora-postgresql,'aurora-postgresql')
/bin/sh: -c: line 0: syntax error near unexpected token `aurora-postgresql,'aurora-postgresql''
/bin/sh: -c: line 0: `ifeq (aurora-postgresql,'aurora-postgresql')'
make[1]: *** [prepare-test-example] Error 2
You have indented the ifeq so it looks to make like something it should pass to the shell.
Try either
ifeq ($(ENGINE),'aurora-postgresql')
files := examples/example.yaml
else
files := examples/example.yaml examples/example_test.yaml
endif
prepare-test-example:
#cat $(files) > /tmp/stack_test.yaml
or
prepare-test-example:
#if [ "$(ENGINE)" = "'aurora-postgresql'" ]; then \
cat examples/example.yaml \
; else \
cat examples/example.yaml examples/example_test.yaml \
; fi > /tmp/stack_test.yaml
For fun, I refactored out the redirection in the latter (pure shell script) example.
Perhaps you meant ifeq('$(ENGINE)','aurora-postgresql') which would make more sense, and allow for the above code to be simplified somewhat.

Dynamically generating a list of targets

If a file exists, I want to add a target to build. If the file does not exist, I want the target to be skipped.
an example:
FILENAME = f
TARGETS := normal
ifneq($(shell stat test_$(FILENAME).c), "")
TARGETS += test
endif
all: $(TARGETS)
normal:
#echo normal
test:
#echo test
I'm not sure the $(shell stat ...) part even works, but the bigger problem is that make with any file test_f.c in the current folder gives:
Makefile:4: *** multiple target patterns. Stop.
Removing the ifneq ... endif block makes the target normal. How can I only run the target test if test_f.c exists?
What you can do is generate a string variable (let's call it OPTIONAL) such that when 'test_f.c' exists, OPTIONAL=test; otherwise, OPTIONAL=_nothing_. And then add OPTIONAL as a prerequisite of all. e.g.:
FILENAME = f
TARGETS = normal
OPTIONAL = $(if $(wildcard test_f.c), test, )
all: $(TARGETS) $(OPTIONAL)
normal:
#echo normal
test:
#echo test
You can also iterate over targets with for loop
.PHONY: all
RECIPES = one
all: RECIPES += $(if $(wildcard test_f.c), two, )
all:
for RECIPE in ${RECIPES} ; do \
$(MAKE) $${RECIPE} ; \
done
one:
$(warning "One")
two:
$(warning "Two")
> make
for RECIPE in one ; do \
/Applications/Xcode.app/Contents/Developer/usr/bin/make ${RECIPE} ; \
done
makefile:11: "One"
make[1]: `one' is up to date.
> touch test_f.c
> make
for RECIPE in one two ; do \
/Applications/Xcode.app/Contents/Developer/usr/bin/make ${RECIPE} ; \
done
makefile:11: "One"
make[1]: `one' is up to date.
makefile:14: "Two"
make[1]: `two' is up to date.

latex makefile not finding png: make: *** No rule to make target `pngfigure.pdf', needed by `main.pdf'. Stop

I'm having trouble getting one of my documents to compile. I've used this makefile before no problems. However, this time, It seems to have a problem recognising .png figures and tries to load them as .pdf.
main.tex
\documentclass[letterpaper, 10 pt, conference]{ieeeconf} % Comment this line out
% if you need a4paper
%\documentclass[a4paper, 10pt, conference]{ieeeconf} % Use this line for a4
% paper
\IEEEoverridecommandlockouts % This command is only
% needed if you want to
% use the \thanks command
\overrideIEEEmargins
% See the \addtolength command later in the file to balance the column lengths
% on the last page of the document
% The following packages can be found on http:\\www.ctan.org
\usepackage{graphics} % for pdf, bitmapped graphics files
\usepackage{epsfig} % for postscript graphics files
\usepackage{mathptmx} % assumes new font selection scheme installed
\usepackage{times} % assumes new font selection scheme installed
\usepackage{amsmath} % assumes amsmath package installed
\usepackage{amssymb} % assumes amsmath package installed
\usepackage{graphicx} % Include figures
\usepackage{float} % Include figures
\graphicspath{{./Figures/}} %Where the figures folder is located
\title{\LARGE \bf
.
.
.
\begin{document}
.
.
.
\begin{figure}[thpb]
\centering
\includegraphics[width=3in]{pngfigure}
\caption{pngfigure}
\label{fig:pngfigure}
\end{figure}
.
.
.
and my Makefile
# Makefile for LaTeX files
LATEX = pdflatex
BIBTEX = bibtex
MAKEINDEX = makeindex
OUTPUT_PDF_FILE_NAME = phd_conversion_report
RERUN = "(There were undefined references|Rerun to get (cross-references|the bars) right)"
RERUNBIB = "No file.*\.bbl|Citation.*undefined"
MAKEIDX = "^[^%]*\\makeindex"
MPRINT = "^[^%]*print"
USETHUMBS = "^[^%]*thumbpdf"
SRC := $(shell egrep -l '^[^%]*\\begin\{document\}' *.tex)
BIBFILE := $(shell perl -ne '($$_)=/^[^%]*\\bibliography\{(.*?)\}/;#_=split /,/;foreach $$b (#_) {print "$$b.bib "}' $(SRC))
PDFPICS := $(shell perl -ne '#foo=/^[^%]*\\(includegraphics)(\[.*?\])?\{(.*?)\}/g;if (defined($$foo[2])) { if ($$foo[2] =~ /.pdf$$/) { print "$$foo[2] "; } else { print "$$foo[2].pdf "; }}' *.tex)
DEP = *.tex
TRG = $(SRC:%.tex=%.pdf)
COPY = if test -r $(<:%.tex=%.toc); then cp $(<:%.tex=%.toc) $(<:%.tex=%.toc.bak); fi
RM = rm -f
OUTDATED = echo "EPS-file is out-of-date!" && false
all: $(TRG) copy clean
define run-latex
$(COPY);$(LATEX) $<
egrep -q $(MAKEIDX) $< && ($(MAKEINDEX) $(<:%.tex=%);$(COPY);$(LATEX) $<) ; true
egrep -c $(RERUNBIB) $(<:%.tex=%.log) && ($(BIBTEX) $(<:%.tex=%);$(COPY);$(LATEX) $<) ; true
egrep -q $(RERUN) $(<:%.tex=%.log) && ($(COPY);$(LATEX) $<) ; true
egrep -q $(RERUN) $(<:%.tex=%.log) && ($(COPY);$(LATEX) $<) ; true
if cmp -s $(<:%.tex=%.toc) $(<:%.tex=%.toc.bak); then true ;else $(LATEX) $< ; fi
$(RM) $(<:%.tex=%.toc.bak)
# Display relevant warnings
egrep -i "(Reference|Citation).*undefined" $(<:%.tex=%.log) ; true
endef
$(TRG): %.pdf: %.tex $(DEP) $(PDFPICS) $(BIBFILE)
#$(run-latex); \
PHONY: copy
copy:
cp $(TRG:%.pdf=%.pdf) $(OUTPUT_PDF_FILE_NAME).pdf
.PHONY: clean
clean:
-rm -f $(TRG) $(PSF) $(TRG:%.pdf=%.aux) $(TRG:%.pdf=%.bbl) $(TRG:%.pdf=%.blg) $(TRG:%.pdf=%.log) $(TRG:%.pdf=%.out); \
$(RM) *.toc *.lot *.lof *.log Sections/*.aux Sections/*.fls Sections/*.log Sections/*.fdb*; \
.PHONY: cleanpdf
cleanpdf:
-rm -f $(TRG) $(PSF) $(PDF) $(TRG:%.pdf=%.aux) $(TRG:%.pdf=%.bbl) $(TRG:%.pdf=%.blg) $(TRG:%.pdf=%.log) $(TRG:%.pdf=%.out); \
$(RM) *.toc *.lot *.lof Sections/*.aux Sections/*.fls Sections/*.log Sections/*.fdb*; \
$(RM) $(OUTPUT_PDF_FILE_NAME).pdf; \
.PHONY: view
view:
acroread $(TRG:%.pdf=%.pdf)
.PHONY: osx
osx:
open $(TRG:%.pdf=%.pdf)
.PHONY: count
count:
texcount main.tex
######################################################################
# Define rules for PDF source files.
.PHONY: pdf
%.pdf: %.eps
epstopdf $< > $(<:%.eps=%.pdf)
Running make, I get the error:
make: *** No rule to make target `pngfigure.pdf', needed by `main.pdf'. Stop.
If I run
$ pdflatex main.tex
It compiles fine and the images show up. The error only happens with make.
Also, as an add on to this question, in the makefile I use texcount to count the words, I couldn't figure out how to get it to load the main.tex file no matter what it was called. I had to resort to the actual filename. I think it should be something like
texcount %.tex
But that doesn't work
This error:
make: *** No rule to make target `pngfigure.pdf', needed by `main.pdf'. Stop.
means that you listed pngfigure.pdf as a prerequisite of main.pdf but that make doesn't know how to build that.
It doesn't know how to build that, presumably, because it isn't actually a pdf file (or a tex file that can be converted to a pdf file).
The incorrect prerequisite here is coming from the PDFPICS macro which is finding all the \includegraphics entries in the tex file and then spitting out $name.pdf for them. Clearly, at least in that case that is incorrect.
Additionally, simply updating the PDFPICS macro to use png instead of pdf is not enough if the images are not in the current directory (as they appear not to be in this case).
For that you'll need to incorporate parsing of \graphicspath from the document as well to include that in the PDFPICS generated prerequisites.

In Kernel makefile $(call cmd, tags) what is the cmd here refers to?

In Kernel Makefile i found the code like below:
ctags CTAGS CSCOPE: $(HEADERS) $(SOURCES)
$(ETAGS) $(ETAGSFALGS) $(HEADERS) $(SOURCES)
$(call cmd, ctags)
Also, where can i find the Macro or function ?
Using MadScientist's method on kernel v4.1:
make -p | grep -B1 -E '^cmd '
we find:
# makefile (from `scripts/Kbuild.include', line 211)
cmd = #$(echo-cmd) $(cmd_$(1))
scripts/Kbuild.include is included on the top level Makefile. It also contains:
echo-cmd = $(if $($(quiet)cmd_$(1)),\
echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
quiet: set at the top level makefile, depending on the value of V.
Will be either:
quiet_ to print CC file.c
empty to print the command on V=
silent_ to not print anything on make -s
escsq is defined as:
squote := '
escsq = $(subst $(squote),'\$(squote)',$1)
It escapes single quotes so that echo '$(call escsq,Letter 'a'.' will print properly in sh.
echo-why: defined further down at Kbuild.include.
It is used for make V=2, and says why a target is being remade.
The setup of make tags is done in the Makefile:
quiet_cmd_tags = GEN $#
cmd_tags = $(CONFIG_SHELL) $(srctree)/scripts/tags.sh $#
tags TAGS cscope gtags: FORCE
$(call cmd,tags)
Which shows the typical usage pattern for calling commands on kbuild:
quiet_cmd_XXX = NAME $#
cmd_XXX = actual-command $#
target: prerequisites
$(call cmd,tags)
A comment on the Makefile explains how all of this is done to make the make output prettier:
# Beautify output
# ---------------------------------------------------------------------------
#
# Normally, we echo the whole command before executing it. By making
# that echo $($(quiet)$(cmd)), we now have the possibility to set
# $(quiet) to choose other forms of output instead, e.g.
#
# quiet_cmd_cc_o_c = Compiling $(RELDIR)/$#
# cmd_cc_o_c = $(CC) $(c_flags) -c -o $# $<
If you run make -p it will print the entire database of all variables, rules, etc. with line numbers where they were last defined.

Resources