Makefile with sed throwing *** target pattern contains no '%'. Stop - shell

I have a Makefile in which I need to pass an image name to another script but the issue is, Image Name has : and - in its line for eg: image.name-v1:latest. As per google make file having : in variable causes issue. How to resolve this issue in Makefile. Below is the sample code that I am trying in which IMAGE has image.name-v1:latest
IMAGE2 ?= ''
.PHONY: image
image:
IMAGE2 := $(subst :,\:,$(IMAGE_R)) ## IMAGE_R is a run time variable for make target
rr/image.sh $(IMAGE2)
Error:
IMAGE2 := docker-rs\:latest ## Test Image using Image Reference
/bin/sh: 1: IMAGE2: not found
Makefile:75: recipe for target 'image' failed
make: *** [image] Error 127
SHELL SCRIPT: image.sh
#!/bin/bash
set -ex
IMAGE="$1"
echo "Image: $IMAGE"

You could try escaping the colon like this:
# Mock IMAGE with colon in name
IMAGE := test:123
# Create new variable adding an escapeing slash
IMAGE2 := $(subst :,\:,$(IMAGE))
# Use IMAGE2 from here on
$(info IMAGE $(IMAGE))
$(info IMAGE2 $(IMAGE2))
.PHONY: xyz-pp
xyz-pp: $(IMAGE2)
.PHONY: $(IMAGE2)
$(IMAGE2):
#echo "1234" > $(IMAGE2)
#ls
#rr/image.sh $(IMAGE2)
I added a script in sub folder rr:
echo "------------- SCRIPT ----------"
echo PARAM: $1
echo $(find -name "$1")
echo "------------- SCRIPT ----------"
output:
> make
IMAGE test:123
IMAGE2 test\:123
makefile rr test:123
------------- SCRIPT ----------
PARAM: test:123
./test:123
------------- SCRIPT ----------
So here I just replace ":" with ":" into a variable IMAGE2 and then use that.
Note: I tested this by just echo'ing your command (since I don't have that file) and touch'ing IMAGE2 to create the file

Related

Function for rendering text in makefile

I create a function rendering input text(argument)
#Color renderning
define GPrint
kColorRed := "\x1b[0;31m"
kColorGreen := "\x1b[0;32m"
kColorEnd := "\x1b[0m"
#echo -e "${kColorGreen}${1}${kColorEnd}"
endef
when I call this funtion
.PHONY : create_odir
create_odir:
$(call GPrint "create output dir")
mkdir ./output_dir
I got this error message
kColorRed := "\x1b[0;31m"
/bin/sh: line 1: kColorRed: command not found
make: *** [../src/sw/makefile:51: create_odir] Error 127
How do I solved it?
Please see below code which will help you fix this issue.
Method 1: Using global variables
# Regular Colors
kColorRed ='\e[0;31m' # Red
kColorGreen ='\e[0;32m' # Green
kColorEnd='\e[0m' # Text Reset
# Color renderning
define GPrint
echo -e ${kColorRed}$(1)${kColorEnd}
echo -e ${kColorGreen}$(1)${kColorEnd}
endef
create_odir:
$(call GPrint ,"create output dir")
Output :
Method 2:
If you want to use local variables inside the function.
# Color renderning
define GPrint
$(eval kColorRed := '\e[0;31m')
$(eval kColorGreen := '\e[0;32m')
$(eval kColorEnd := '\e[0m')
echo -e $(kColorRed)$(1)$(kColorEnd)
echo -e $(kColorGreen)$(1)$(kColorEnd)
endef
create_odir:
$(call GPrint ,"create output dir")

How can I deal with Makefile syntax error made by "tab"?

I am not familiar with shell. I just want to successfully run this piece of code which I downloaded from Github. When I directly ran the code with the command,
make file='example.txt' file_test
it didn't work, and here is the error.
makefile line 1: syntax error: unexpected end of file
I tried to fix the problem by unifying the encoding format of 'Makefile.sh' and 'example.txt' to be Unix, but still it did not work at all.
Then I asked my friend(he is also new to shell), and he told me to delete the "tab" before each line(not including the command lines). The error is different at this time, but I still could not fix it by using Google.
Makefile:75: *** commands commence before first target. Stop.
Please, somebody can help? It is driving me crazy and I have no time left for solving this problem. :( Thanks!!!
And, here is the code after I deleted the 'TAB'.
# State-of-the-art paper: http://www.aclweb.org/anthology/P18-1016
########################################Definitions########################################
SHELL := /bin/bash
NC := \033[0m
RED := \033[0;31m
GREEN := \033[0;32m
CYAN := \033[0;36m
work_dir := $(PWD)
script_dir := $(work_dir)/scripts
NTS_dir := $(work_dir)/NeuralTextSimplification_model
file?=""
filetype := $(shell file $(file) | cut -d: -f2)
article_name := $(basename $(notdir $(file)))
article_simple := $(basename $(file))-simple.txt
NTS_script := $(NTS_dir)/src/scripts/translate.sh
NTS_input := $(NTS_dir)/data/test.en
NTS_result_file = $(NTS_dir)/results_NTS/result_NTS_epoch11_10.19.t7_5
# passage = xml file representing a sentence parsed with TUPA
sentence_dir = $(script_dir)/sentences/$(article_name)
passage_dir = $(script_dir)/passages/$(article_name)
sentences = $(sentence_dir)/*.txt
passages = $(passage_dir)/*.xml
############################################################################################
.SILENT:
.ONESHELL: # To execute all commands in one single bash shell
.PHONY: all file_test NTS DSS tupa_parse split_to_sentences help clean
all: file_test $(article_simple)
printf "\n${GREEN}Article simplified :\n====================${NC}\n\n"
cat $(article_simple)
# evaluate the system results using BLUE & SARI metrics
# The original test.en must be given to evaluate (https://github.com/senisioi/NeuralTextSimplification)
evaluate: all
printf "\n${GREEN}Evaluating: (the original test.en must be given)${NC}\n\n"
python $(NTS_dir)/src/evaluate.py $(NTS_input) $(NTS_dir)/data/references/references.tsv $(NTS_dir)/predictions
############################################################################################
# The following targets are only useful as aliases for testing
# Generates the corresponding NTS model result file.
NTS: file_test $(NTS_result_file)
# Generates the article sentences split using the two semantic rules mentioned in the paper.
DSS: file_test $(NTS_input)
# Parses the article's sentences using TUPA -> output : xml files
tupa_parse: file_test $(passages)
# Splits the article into sentences, each one in a single file
split_to_sentences: file_test $(sentences)
#############################################################################################
# Testing the validity of the file
file_test:
# Whether the file was provided as an argument
if [ $(file) = "" ]; then
printf "${RED}ERROR${NC}: One & only file must be given in argument! Please specify it by:\nmake file=<file_name> <target>\n\n"; exit 1
fi
# Whether the file exists
if [ ! -f $(file) ]; then
printf "$(RED)ERROR${NC}: $(file) File not found!\n\n"; exit 1
fi
# Whether the file is empty
if [ ! -s $(file) ]; then
printf "$(RED)ERROR${NC}: $(file) is empty!\n\n"; exit 1
fi
# Whether it is a text file
if [[ ! "$(filetype)" = *"ASCII"* && ! "$(filetype)" = *"UTF-8"* ]]; then
printf "$(RED)ERROR${NC}: Only text files (ASCII or UTF-8 Unicode text) are accepted!\n\n"; exit 1
fi
# Prints help on the useful targets for the user
help:
printf "\n${CYAN}make file=<file_path>${NC} : Executes the simplification completely and avoids rebuilding if unnecessary.\n\n"
printf "${CYAN}make file=<file_path> file_test${NC} : Tests whether the given file is valid.\n\n"
printf "${CYAN}make file=<file_path> NTS${NC} : Generates the corresponding NTS model result file.\n\n"
printf "${CYAN}make file=<file_path> DSS${NC} : Generates the article's sentences split using the two semantic rules mentioned in the paper.\n\n"
printf "${CYAN}make file=<file_path> tupa_parse${NC} : Parses the article's sentences using TUPA -> output : xml files.\n\n"
printf "${CYAN}make file=<file_path> split_to_sentences${NC} : Splits the article into sentences, each one in a single file.\n\n"
printf "${CYAN}make clean${NC} : Cleans results of previous executions.\n\n"
##############################################################################################
# Produces the simple version of text as an output and writes it to "article_simple" variable
$(article_simple): $(NTS_result_file)
cd $(work_dir)
cat $(NTS_result_file) > $(article_simple)
# Equivalent for target NTS
$(NTS_result_file): $(NTS_script) $(NTS_input)
printf "\n${GREEN}Simplifying sentences using the NTS model : ... ${NC}\n\n"
cd $(NTS_dir)/src/scripts/
source ./translate.sh
# Equivalent for target DSS
$(NTS_input): $(script_dir)/split_sentences.py $(passages)
printf "\n${GREEN}Splitting the article's sentences : ... ${NC}\n"
python $(script_dir)/split_sentences.py $(passage_dir) > $(NTS_input)
# If the output of the splitting is empty, then it failed
if [ ! -s $(NTS_input) ]; then
printf "$(RED)ERROR${NC}: Splitting failed!\n\n"; exit 1
fi
# Equivalent for target tupa_parse
$(passages): $(sentences) | $(passage_dir)
printf "\n${GREEN}Parsing the article's sentences : ... ${NC}\n\n"
python -m tupa $(sentences) -m $(work_dir)/TUPA_models/ucca-bilstm
mv *.xml $(passage_dir)
# Equivalent for target split_to_sentences
$(sentences): $(file) $(script_dir)/article_to_sentences.py | $(sentence_dir)
python $(script_dir)/article_to_sentences.py $(file)
# Creates the passage directory
$(passage_dir): $(file)
if [ -d $(passage_dir) ]; then
rm -f $(passage_dir)/*.xml
else
mkdir -p $(script_dir)/passages/
mkdir $(passage_dir)/
fi
# Creates the sentence directory
$(sentence_dir): $(file)
if [ -d $(sentence_dir) ]; then
rm -f $(sentence_dir)/*.txt
else
mkdir -p $(script_dir)/sentences/
mkdir $(sentence_dir)
fi
# Cleans the residues from previous executions
clean:
rm -rf $(passage_dir)* $(sentence_dir)*
echo > $(NTS_result_file)

Makefile does not find target

I have the following Makefile, but it does not work. When I call
make html
I get a
make: *** No rule to make target `docs/index.html', needed by `html'. Stop.
error, even though I think I have defined it.
SRCDIR = source
OUTDIR = docs
RMD = $(wildcard $(SRCDIR)/*.Rmd)
TMP = $(RMD:.Rmd=.html)
HTML = ${subst $(SRCDIR),$(OUTDIR),$(TMP)}
test:
echo $(RMD)
echo $(TMP)
echo $(HTML)
all: clean update html
html: $(HTML)
%.html: %.Rmd
echo $(HTML)
#Rscript -e "rmarkdown::render('$<', output_format = 'prettydoc::html_pretty', output_dir = './$(OUTDIR)/')"
update:
#Rscript -e "devtools::load_all(here::here()); microcosmScheme:::updateFromGoogleSheet(token = './source/googlesheets_token.rds')"
## from https://stackoverflow.com/a/26339924/632423
list:
#$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$#$$' | xargs
.PHONY: update clean cleanhtml all list
The variables seem to be correct:
15:21 $ make test
echo source/index.Rmd
source/index.Rmd
echo source/index.html
source/index.html
echo docs/index.html
docs/index.html
If I change it as follow it works, but the target points to the SRCDIR, but I want it to point to the OUTDIR:
RMD = $(wildcard $(SRCDIR)/*.Rmd)
HTML = $(RMD:.Rmd=.html)
# HTML = ${subst $(SRCDIR),$(OUTDIR),$(TMP)}
I am sure it is one small thing...
This rule:
%.html : %.Rmd
....
tells make how to build a file foo.html from a file foo.Rmd, or a file source/foo.html from a file source/foo.Rmd, or a file docs/foo.html from a file docs/foo.Rmd.
It doesn't tell make how to build a file docs/foo.html from a file source/foo.Rmd, because the stem that matches the pattern % is not the same.
If you want to write a pattern for docs/foo.html to be built from source/foo.Rmd, you have to write it like this:
$(OUTDIR)/%.html : $(SRCDIR)/%.Rmd
....
so that the part that matches the pattern % is identical.
ETA Some other notes: you should be using := with the wildcard function as it's much better performing. Also you shouldn't use subst here because it replaces all occurrences of the string which could break things if any of your .Rmd files contain the string source for example (e.g., source/my_source_file.Rmd. This is much better written with patsubst, as in:
RMD := $(wildcard $(SRCDIR)/*.Rmd)
HTML := $(patsubst $(SRCDIR)/%.Rmd,$(OBJDIR)/%.html,$(RMD))
Finally, you don't show what the clean target does but it's unusual to have the clean target depended on by all. Usually it's a separate target that is invoked only when you want it, like make clean.

How to call Makefile recipe/rule multiple times?

With the following example:
.PHONY: hook1 hook2
# Default target
all: hook1 hook2 hook1
echo "Calling all"
hook1:
echo "Calling hook1"
hook2:
echo "Calling hook2"
I got the output:
$ make
echo "Calling hook1"
Calling hook1
echo "Calling hook2"
Calling hook2
echo "Calling all"
Calling all
But I would expect it to call the rule hook1 two times. This is because on Latex, I need to call the same program with the same command line, multiple times. Then I would like to reuse the make rules. For example, I would expect the above minimal code to be ran as:
$ make
echo "Calling hook1"
Calling hook1
echo "Calling hook2"
Calling hook2
echo "Calling hook1"
Calling hook1
echo "Calling all"
Calling all
Which call the same rule twice. This is code bellow my full main Makefile code, if anyone is interested. I tried to create the dummy rules pdflatex_hook1 and pdflatex_hook2 so I could do the call hierarchy pdflatex_hook biber_hook pdflatex_hook, but this do not fooled make and it still ignoring my last call to pdflatex_hook2:
#!/usr/bin/make -f
# https://stackoverflow.com/questions/7123241/makefile-as-an-executable-script-with-shebang
ECHOCMD:=/bin/echo -e
# The main latex file
THESIS_MAIN_FILE = modelomain.tex
# This will be the pdf generated
THESIS_OUTPUT_NAME = thesis
# This is the folder where the temporary files are going to be
CACHE_FOLDER = setup/cache
# Find all files ending with `main.tex`
LATEX_SOURCE_FILES := $(wildcard *main.tex)
# Create a new variable within all `LATEX_SOURCE_FILES` file names ending with `.pdf`
LATEX_PDF_FILES := $(LATEX_SOURCE_FILES:.tex=.pdf)
# GNU Make silent by default
# https://stackoverflow.com/questions/24005166/gnu-make-silent-by-default
MAKEFLAGS += --silent
.PHONY: clean pdflatex_hook1 pdflatex_hook2 %.pdf %.tex
# How do I write the 'cd' command in a makefile?
# http://stackoverflow.com/questions/1789594/how-do-i-write-the-cd-command-in-a-makefile
.ONESHELL:
# Default target
all: biber
##
## Usage:
## make <target>
##
## Targets:
## biber build the main file with bibliography pass
## pdflatex build the main file with no bibliography pass
##
# Print the usage instructions
# https://gist.github.com/prwhite/8168133
help:
#fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
# Where to find official (!) and extended documentation for tex/latex's commandline options (especially -interaction modes)?
# https://tex.stackexchange.com/questions/91592/where-to-find-official-and-extended-documentation-for-tex-latexs-commandlin
PDF_LATEX_COMMAND = pdflatex --time-statistics --synctex=1 -halt-on-error -file-line-error
LATEX = $(PDF_LATEX_COMMAND)\
--interaction=batchmode\
-jobname="$(THESIS_OUTPUT_NAME)"\
-output-directory="$(CACHE_FOLDER)"\
-aux-directory="$(CACHE_FOLDER)"
# Run pdflatex, biber, pdflatex
biber: biber_hook pdflatex_hook2
# Calculate the elapsed seconds and print them to the screen
. ./setup/scripts/timer_calculator.sh
showTheElapsedSeconds "$(current_dir)"
# Internally called rule which does not attempt to show the elapsed time
biber_hook: pdflatex_hook1
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
biber "$(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME)"
# This rule will be called for every latex file and pdf associated
pdflatex: $(LATEX_PDF_FILES)
# Calculate the elapsed seconds and print them to the screen
. ./setup/scripts/timer_calculator.sh
showTheElapsedSeconds "$(current_dir)"
# Not show the elapsed time when called internally
pdflatex_hook1: $(LATEX_PDF_FILES)
pdflatex_hook2: $(LATEX_PDF_FILES)
%.pdf: %.tex
# Start counting the compilation time and import its shell functions
. ./setup/scripts/timer_calculator.sh
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
#$(LATEX) $<
cp $(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME).pdf $(current_dir)/$(THESIS_OUTPUT_NAME).pdf
Here when I call the rule make biber I got the output:
$ make biber
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (MiKTeX 2.9.6400)
entering extended mode
gross execution time: 62751 ms
user mode: 58406 ms, kernel mode: 1359 ms, total: 59765
INFO - This is Biber 2.7
INFO - Logfile is 'setup/cache/thesis.blg'
INFO - Reading 'setup/cache/thesis.bcf'
INFO - Found 14 citekeys in bib section 0
INFO - Processing section 0
INFO - Looking for bibtex format file 'modeloreferences.bib' for section 0
INFO - Decoding LaTeX character macros into UTF-8
INFO - Found BibTeX data source 'modeloreferences.bib'
INFO - Overriding locale 'pt-BR' defaults 'normalization = NFD' with 'normalization = prenormalized'
INFO - Overriding locale 'pt-BR' defaults 'variable = shifted' with 'variable = non-ignorable'
INFO - Sorting list 'nty/global/' of type 'entry' with scheme 'nty' and locale 'pt-BR'
INFO - No sort tailoring available for locale 'pt-BR'
INFO - Writing 'setup/cache/thesis.bbl' with encoding 'UTF-8'
INFO - Output to setup/cache/thesis.bbl
Could not calculate the seconds to run
Which is missing the second call to the rule pdflatex_hook2, only the first call to pdflatex_hook1 is being performed.`
I already know about latexmk and use it, but for biber above I would like to do these calls as they are. For latexmk I use this recipe/rule:
thesis: $(THESIS_MAIN_FILE)
# Start counting the compilation time and import its shell functions
. ./setup/scripts/timer_calculator.sh
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
# What is the difference between “-interaction=nonstopmode” and “-halt-on-error”?
# https://tex.stackexchange.com/questions/258814/what-is-the-difference-between-interaction-nonstopmode-and-halt-on-error
#
# What reasons (if any) are there for compiling in interactive mode?
# https://tex.stackexchange.com/questions/25267/what-reasons-if-any-are-there-for-compiling-in-interactive-mode
latexmk \
-pdf \
-silent \
-jobname="$(THESIS_OUTPUT_NAME)" \
-output-directory="$(CACHE_FOLDER)" \
-aux-directory="$(CACHE_FOLDER)" \
-pdflatex="$(PDF_LATEX_COMMAND) --interaction=batchmode" \
-use-make $(THESIS_MAIN_FILE)
# Copy the generated PDF file from the cache folder
cp $(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME).pdf $(current_dir)/$(THESIS_OUTPUT_NAME).pdf
# Calculate the elapsed seconds and print them to the screen
showTheElapsedSeconds "$(current_dir)"
Related questions:
Change a make variable, and call another rule, from a recipe in same Makefile?
How to manually call another target from a make target?
multiple targets from one recipe and parallel execution
To answer your initial question:
.PHONY: hook1 hook2
# Default target
all: hook1a hook2 hook1b
echo "Calling all"
hook1a hook1b:
echo "Calling hook1"
hook2:
echo "Calling hook2"
Produces the following output:
echo "Calling hook1"
Calling hook1
echo "Calling hook2"
Calling hook2
echo "Calling hook1"
Calling hook1
echo "Calling all"
Calling all
As illustrated in make recipe execute twice
Based on #David White answer I fixed my main script with the double recursion:
#!/usr/bin/make -f
# https://stackoverflow.com/questions/7123241/makefile-as-an-executable-script-with-shebang
ECHOCMD:=/bin/echo -e
# The main latex file
THESIS_MAIN_FILE = modelomain.tex
# This will be the pdf generated
THESIS_OUTPUT_NAME = thesis
# This is the folder where the temporary files are going to be
CACHE_FOLDER = setup/cache
# Find all files ending with `main.tex`
LATEX_SOURCE_FILES := $(wildcard *main.tex)
# Create a new variable within all `LATEX_SOURCE_FILES` file names ending with `.pdf`
LATEX_PDF_FILES := $(LATEX_SOURCE_FILES:.tex=.pdf)
# GNU Make silent by default
# https://stackoverflow.com/questions/24005166/gnu-make-silent-by-default
MAKEFLAGS += --silent
.PHONY: clean biber pdflatex_hook1 pdflatex_hook2
# How do I write the 'cd' command in a makefile?
# http://stackoverflow.com/questions/1789594/how-do-i-write-the-cd-command-in-a-makefile
.ONESHELL:
# Default target
all: thesis
##
## Usage:
## make <target>
##
## Targets:
## all call the `thesis` make rule
## biber build the main file with bibliography pass
## latex build the main file with no bibliography pass
## thesis completely build the main file with minimum output logs
## verbose completely build the main file with maximum output logs
##
# Print the usage instructions
# https://gist.github.com/prwhite/8168133
help:
#fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
# Where to find official (!) and extended documentation for tex/latex's commandline options (especially -interaction modes)?
# https://tex.stackexchange.com/questions/91592/where-to-find-official-and-extended-documentation-for-tex-latexs-commandlin
PDF_LATEX_COMMAND = pdflatex --time-statistics --synctex=1 -halt-on-error -file-line-error
LATEX = $(PDF_LATEX_COMMAND)\
--interaction=batchmode\
-jobname="$(THESIS_OUTPUT_NAME)"\
-output-directory="$(CACHE_FOLDER)"\
-aux-directory="$(CACHE_FOLDER)"
# Run pdflatex, biber, pdflatex
biber: start_timer pdflatex_hook1 biber_hook pdflatex_hook2
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
# Copies the PDF to the current folder
cp $(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME).pdf $(current_dir)/$(THESIS_OUTPUT_NAME).pdf
# Calculate the elapsed seconds and print them to the screen
. ./setup/scripts/timer_calculator.sh
showTheElapsedSeconds "$(current_dir)"
start_timer:
# Start counting the elapsed seconds to print them to the screen later
. ./setup/scripts/timer_calculator.sh
# Internally called rule which does not attempt to show the elapsed time
biber_hook:
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
# Call biber to process the bibliography
biber "$(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME)"
# How to call Makefile recipe/rule multiple times?
# https://stackoverflow.com/questions/46135614/how-to-call-makefile-recipe-rule-multiple-times
pdflatex_hook1 pdflatex_hook2:
#$(LATEX) $(LATEX_SOURCE_FILES)
# This rule will be called for every latex file and pdf associated
latex: $(LATEX_PDF_FILES)
# Calculate the elapsed seconds and print them to the screen
. ./setup/scripts/timer_calculator.sh
showTheElapsedSeconds "$(current_dir)"
# Dynamically generated recipes for all PDF and latex files
%.pdf: %.tex
# Start counting the compilation time and import its shell functions
. ./setup/scripts/timer_calculator.sh
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
#$(LATEX) $<
cp $(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME).pdf $(current_dir)/$(THESIS_OUTPUT_NAME).pdf
thesis: $(THESIS_MAIN_FILE)
# Start counting the compilation time and import its shell functions
. ./setup/scripts/timer_calculator.sh
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
# What is the difference between “-interaction=nonstopmode” and “-halt-on-error”?
# https://tex.stackexchange.com/questions/258814/what-is-the-difference-between-interaction-nonstopmode-and-halt-on-error
#
# What reasons (if any) are there for compiling in interactive mode?
# https://tex.stackexchange.com/questions/25267/what-reasons-if-any-are-there-for-compiling-in-interactive-mode
latexmk \
-pdf \
-silent \
-jobname="$(THESIS_OUTPUT_NAME)" \
-output-directory="$(CACHE_FOLDER)" \
-aux-directory="$(CACHE_FOLDER)" \
-pdflatex="$(PDF_LATEX_COMMAND) --interaction=batchmode" \
-use-make $(THESIS_MAIN_FILE)
# Copy the generated PDF file from the cache folder
cp $(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME).pdf $(current_dir)/$(THESIS_OUTPUT_NAME).pdf
# Calculate the elapsed seconds and print them to the screen
showTheElapsedSeconds "$(current_dir)"
verbose: $(THESIS_MAIN_FILE)
# Start counting the compilation time and import its shell functions
. ./setup/scripts/timer_calculator.sh
# Creates the shell variable `current_dir` within the current folder path
$(eval current_dir := $(shell pwd)) echo $(current_dir) > /dev/null
# What is the difference between “-interaction=nonstopmode” and “-halt-on-error”?
# https://tex.stackexchange.com/questions/258814/what-is-the-difference-between-interaction-nonstopmode-and-halt-on-error
#
# What reasons (if any) are there for compiling in interactive mode?
# https://tex.stackexchange.com/questions/25267/what-reasons-if-any-are-there-for-compiling-in-interactive-mode
latexmk \
-pdf \
-jobname="$(THESIS_OUTPUT_NAME)" \
-output-directory="$(CACHE_FOLDER)" \
-aux-directory="$(CACHE_FOLDER)" \
-pdflatex="$(PDF_LATEX_COMMAND) --interaction=nonstopmode" \
-use-make $(THESIS_MAIN_FILE)
# Copy the generated PDF file from the cache folder
cp $(CACHE_FOLDER)/$(THESIS_OUTPUT_NAME).pdf $(current_dir)/$(THESIS_OUTPUT_NAME).pdf
# Calculate the elapsed seconds and print them to the screen
showTheElapsedSeconds "$(current_dir)"
# Using Makefile to clean subdirectories
# https://stackoverflow.com/questions/26007005/using-makefile-to-clean-subdirectories
#
# Exclude directory from find . command
# https://stackoverflow.com/questions/4210042/exclude-directory-from-find-command
GARBAGE_TYPES := "*.gz(busy)" *.aux *.log *.pdf *.aux *.bbl *.log *.out *.toc *.dvi *.blg\
*.synctex.gz *.fdb_latexmk *.fls *.lot *.lol *.lof *.idx
DIRECTORIES_TO_CLEAN := $(shell /bin/find -not -path "./**.git**" -not -path "./pictures**" -type d)
GARBAGE_TYPED_FOLDERS := $(foreach DIR, $(DIRECTORIES_TO_CLEAN), $(addprefix $(DIR)/,$(GARBAGE_TYPES)))
clean:
rm -rfv $(GARBAGE_TYPED_FOLDERS)
# veryclean:
# git clean -dxf

Makefile: read input variable and set several variables

I have a makefile where I want to read file name from input and then make other names based on it`s name. I have tried the following code
mlext = .ml
testext = test.ml
nativeext = test.native
test:
#read -p "Enter file name: " file; \
echo $$file$(mlext); \
echo $$file$(testext); \
echo $$file$(nativeext)
for example:
If i type: foo
then I want to get foo.ml, footest.ml, footest.native
however, I can only get foo.ml. For the rest two i only get .ml and .native
How can i fix this?
First, let us see what is the exact recipe given to the shell by removing the # in your Makefile:
read -p "Enter file name: " file; \
echo $file.ml; \
echo $filetest.ml; \
echo $filetest.native;
The issue is thus that the content of $(testext) gets appended to $$file, creating the shell variable $filetest, which (very probably) does not exist, resulting in an empty string in the end. This does not occur with $(mlext), as the initial dot cannot be part of a variable name.
To overcome this, use $${file} instead of $$file in your Makefile rule.

Resources