makefile latex DVI=$(TEX:.tex=.dvi) meaning - makefile

I have a makefile for a Latex document which contains the following rules:
TEX=index.tex
DVI=$(TEX:.tex=.dvi)
PS=$(TEX:.tex=.ps)
PDF=$(TEX:.tex=.pdf)
all: images $(PDF)
images:
make -C $#
%.dvi: %.tex
latex $<
%.ps: %.dvi
dvips $<
%.pdf: %.ps
ps2pdf $<
what does the syntax DVI=$(TEX:.tex=.dvi) exactly do? how is it expanded? I tried to print the result with an echo but nothing is printed.

That line sets DVI to the same thing as TEX but substitutes .tex for .dvi

Related

Makefile seems to take both inputs instead of one at a time

I have two files 1.gv and 2.gv which are Graphviz files.
I wrote this Makefile from what I could figure out:
DOT=dot
FORMAT=svg
SRC=$(wildcard *.gv)
OUT=$(subst .gv,.$(FORMAT),$(SRC))
all: $(OUT)
$(OUT): $(SRC)
$(DOT) -T$(FORMAT) $^ -o $#
.PHONY: clean
clean:
rm -f $(OUT)
The clean seems to work, the only problem seems to be is it runs:
dot -Tsvg 1.gv 2.gv -o 1.svg
dot -Tsvg 1.gv 2.gv -o 2.svg
instead of:
dot -Tsvg 1.gv -o 1.svg
dot -Tsvg 2.gv -o 2.svg
In your Makefile make sees that it needs all gv-files (SRC) to make one file: 1.gv (OUT) so in the loop the prerequisite changes $< but not the target $#.
You need to match a pattern and use patsubst instead of subst so OUT is a pattern of files.
I removed most variables for clarity. Feel free to add them back.
SRC = $(wildcard *.gv)
OUT = $(patsubst %.gv,%.svg,$(SRC))
%.svg: %.gv
dot -Tsvg $< -o $#
all: $(OUT)
.PHONY: clean
clean:
$(RM) *.svg

Makefile, rule for all rule patterns

Context
I am using the pattern rule
%.png: %.tex
compile.sh $<
to generate png files from all available (changed) tex files.
Problem
What I do not get right is that I want to use make all to do that for all of them at once.
all: *.tex
compile.sh $^
However, $^ seems to be always replaced by all tex files and not only the changed ones (obviously, the Makefile does not really know about the connection to the png files).
Not working alternative
Using
all: *.png
compile.sh $^
does not make sense when the png files do not exist yet, right?
Is there really some specific reason that you have to do them all with a single command? Why can't you just have all depend on all the .png files?
%.png: %.tex
compile.sh $<
TEXFILES := $(wildcard *.tex)
all: $(TEXFILES:.tex=.png)

error in using tab in makefile how to fix it

when I try to do make for the makefile it shows me (makefile error missing separator. stop)
my make file is
PROGS = $(patsubst %.c,%,$(SRCS))
all: $(PROGS)
%: %.c
arm-linux-gnueabihf-gcc --static $< -o $#
clean:
rm -f $(PROGS)
I try to use the following command but I could not solve my problem
cat -e -t -v Makefile
SRCS^I=^I$(wildcard^I*.c)^I$
PROGS^I=^I$(patsubst^I%.c,%,$(SRCS))$
all:^I$(PROGS)^I$
%:^I%.c^I$
arm-linux-gnueabihf-gcc^I--static^I$<^I-o^I$#^I$
clean:^I$
rm^I-f^I$(PROGS)^I$ ```
Crazy. You have TAB characters in all the places you don't need them, and you don't have TAB characters in any of the (two) places you must have them. I don't know how you managed that.
In your makefile above the places you MUST have TAB chars are the recipe lines. In other words, your makefile should look like this from cat -e -t -v Makefile:
SRCS = $(wildcard *.c)$
PROGS = $(patsubst %.c,%,$(SRCS))$
all: $(PROGS)$
%: %.c$
^Iarm-linux-gnueabihf-gcc --static $< -o $#$
clean:$
^Irm -f $(PROGS)$
As for configuring your text editor, there are a ton of text editors out there, even on Ubuntu, and we have no idea which one you are using.
I recommend you use a programmer's editor, which has a special mode that understands makefile syntax.

Is it possible to create a target that repeats an action for different files?

I'm trying to build a Makefile that simplifies compilation for a C assignment. The Makefile works fine for now, however, I would like to add a new target that executes a previous target and creates files.
The objective is the following:
Compile a given program (figures.c)
Execute it (this creates a bunch of .gv files)
Transform every .gv file to a .pdf file
I know how to transform a single file (I have the command), but can't seem to figure out how to loop through every file, without typing them all out.
I've already tried doing a different type of target, but does not work (see commented target)
# COMPILATION
CC=gcc
CFLAGS=-Wall -ansi -pedantic
# DOSSIERS
SOURCEDOC=sourcedoc
DOC=doc
SRC=src
INC=inc
OBJ=build
FIGS=images
FILES=$(wildcard $(FIGS)/*.gv)
.PHONY: clean doc archive author all
.SILENT : clean
# Targets
all : clean test images
test : $(OBJ)/Test_arbre.o $(OBJ)/aux.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/arbres.o
$(CC) $^ -o $# $(CFLAGS)
figures : $(OBJ)/figures.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/aux.o $(OBJ)/arbres.o
$(CC) $^ -o $# $(CFLAGS)
%.pdf: $(FIGS)/%.gv
dot -Tpdf -o $(FIGS)/$# $^
#$(FILES): $(FIGS)/%.pdf : $(FIGS)/%.gv
# dot -Tpdf -o $# $^
images : figures $(FILES)
#=========== Objets ===========
$(OBJ)/arbres.o : $(INC)/arbres.h $(INC)/aux.h $(INC)/Affichage.h $(INC)/ArbreBinaire.h
$(OBJ)/Affichage.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h
$(OBJ)/exemple*_arbre.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h
$(OBJ)/aux.o : $(INC)/aux.h
$(OBJ)/figures.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(INC)/arbres.h
$(OBJ)/Test_arbre.o : $(INC)/arbres.h $(INC)/ArbreBinaire.h $(INC)/Affichage.h
# Dummy rule
$(OBJ)/%.o : $(SRC)/%.c
#mkdir -p $(#D)
#$(CC) $< $(CFLAGS) -I $(INC)/ -c -o $#
# Miscellaneous
clean:
rm -f *~ */*~
rm -rf __pycache__ src/__pycache__
rm -rf $(DOC)
rm -f $(PROJECT)_$(AUTHOR12)_$(AUTHOR22).zip
rm -f conf.py-e
rm -rf $(OBJ)
rm -f $(FIGS)/*.pdf $(FIGS)/*.gv
rm -f test
The current Makefile works fine on all other commands than images.
If any of you could help, it would mean a lot!
Your definition of FILES should map the *.gv files to the corresponding *.pdf files;
FILES=$(patsubst %.gv,%.pdf,$(wildcard $(FIGS)/*.gv))
The rule which says how to generate a PDF should factor out the directory name;
%.pdf: %.gv
dot -Tpdf -o $# $^
Now, if make tries to create $(FIGS)/ick.pdf, the input will be $(FIGS)/ick.gv - the pattern says to substitute the extension .gv with the extension .pdf, and the rest of the file name stays unmodified, exactly like you'd want. A rule like
%.pdf: $(FIGS)/%.gv # error, don't use
says you need to find the source file in a subdirectory $(FIGS); so if you tried to make $(FIGS)/ick.pdf, that means make would need to find or generate $(FIGS)/$(FIGS)/ick.gv as input according to this rule.
If you absolutely cannot predict what files will be created on step (2) (and so confined to using $(wildcard ...)), you still must execute it after (2) is finished.
It's ugly but I can't think of better alternative than using "recursive make". I mean something like this:
...
.PHONY: images pdf
images: figures
# use figures to generate all .gv files
##figures --create-all-gv-files
# invoke make recursively
#$(MAKE) --no-print-directory pdf
# ensure $(wildcard ...) is invoked only if needed
ifeq ($(MAKECMDGOALS),pdf)
PDF_FILES:=$(patsubst %.gv,%.pdf,$(wildcard $(FIGS)/*.gv))
endif
pdf: $(PDF_FILES)
%.pdf: %.gv
dot -Tpdf -o $# $<

Make: Target name in Rule

I have created a Makefile to generate pdf and html for a md file mentioned while invoking make like make a.md should generate a.pdf and a.html, and should not convert other md files present in the directory.
My make file
But I am, getting error Nothing to be done for a.md
Could you please suggest changes?
Because a.md is already in place, make indeed does have nothing further to do. You can either just use for instance a as the specified target (which can depend on pdf and html files as prerequisites). Or pass the desired source through a variable and determine your desired target from that.
One (the latter) option would be this:
EXPORTED= $(SOURCE:%.md=%.html) $(SOURCE:%.md=%.pdf)
%.html : %.md
pandoc -o $# $<
%.pdf : %.md
pandoc -o $# $<
all: $(EXPORTED)
Which you can call with make SOURCE=a.md.
The other option (former):
%.html : %.md
pandoc -o $# $<
%.pdf : %.md
pandoc -o $# $<
.PHONY: $(MAKECMDGOALS)
$(MAKECMDGOALS): $(MAKECMDGOALS:%=%.html) $(MAKECMDGOALS:%=%.pdf)
Allows you to call make a.
But to reiterate. You cannot use (existing) source as a target, because make would (as it did) conclude it's done making that target.
Except (but I personally do not really like this as it is IMO confusing), if you insisted, you could do a variation on the previous take... but work with *.md targets... which you all declare as .PHONY. I.e. not real files and always to be considered/remade:
%.html : %.md
echo pandoc -o $# $<
%.pdf : %.md
echo pandoc -o $# $<
.PHONY: $(MAKECMDGOALS)
$(MAKECMDGOALS): $(MAKECMDGOALS:%.md=%.html) $(MAKECMDGOALS:%.md=%.pdf)
Now you could indeed call make a.md. I'd still prefer one of the two above.

Resources