Handling file names with space with GNU Make - makefile

I am using GNU Make (v3.80) and I must deal with file names with space. (There is nothing that I can do about the file names per se.) My makefile includes "normal" rules as well as static pattern rules. How can I deal with these files without changing too much my makefile?
I have read and studied previous related questions (here, here, here, and there) but none handle static pattern rules.

A solution combines the "question mark" trick by Mecklenburg combined with shell commands (find and sed) and not using the automatic variable $< but rather $*.
Imagine that you want to copy any files found in a data directory into a target directory, here are the rules (including a static pattern rule). Below is the complete makefile, here are the interesting bits:
EXEDIR = bin/vbcc-classic/AmiModRadio/
DATADIR = $(EXEDIR)data/
DATA = $(addprefix $(DATADIR), $(shell find data/ -mindepth 1 -maxdepth 1 -printf "%f\n" | sed 's/ /?/g'))
In the above, the last variable declaration, DATA contains the set of file names available in data/ with any space in their file names replaced by a ?. Each file name is prefixed by the target directory DATADIR and delimited by spaces.
space :=
space +=
replaceQuestionBySpace = $(subst ?,$(space),$1)
replaceSpaceByQuestion = $(subst $(space),?,$1)
In the above, following Mecklenburg, two functions are defined to replace spaces with question marks and vice-versa.
$(DATA) : $(DATADIR)% : $(wildcard data/%)
cp -f -R "$(call replaceQuestionBySpace,data/$*)" "$(call replaceQuestionBySpace,$#)"
The above is the important static pattern rule: the prerequisite of the rule $(wildcard data/%) ensures that Make will not copy the files in data at each call, but only if they have changed or disappeared from $(DATADIR).
$(wildcard data/%) works because % is replaced by the stem built by $(DATA) : $(DATADIR)% and because $(DATA) contains a set of file names without space (but question marks) and prefixed by $(DATADIR).
In the recipe, question marks are replaced by spaces to get the original file names back. $< cannot be used because it would match to $(wildcard data/%), which would result in an empty string. But, because the target contains $(DATADIR) and the file names, $* can be used (the file names) at the cost of adding data/ in front.
The complete makefile for example.
#
# AmiModRadio
# All of Aminet modules at your fingertips
#
#
#
# Copyright 2015, 2016 Tygre <tygre#chingu.asia>
#
# This file is part of AmiModRadio.
#
# AmiModRadio is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# AmiModRadio is distributed in the hope fthat it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with AmiModRadio. If not, see <http://www.gnu.org/licenses/>.
#
#
#
# Entirely developed on an Amiga!
# (Except for source code versioning...)
# tygre#chingu.asia
#
# Main paths
EXEDIR = bin/vbcc-classic/debug/
OBJECTSDIR = o/vbcc-classic/debug/
# Main paths for release ONLY
ifeq "$(strip $(filter dist, $(MAKECMDGOALS)))" "dist"
EXEDIR = bin/vbcc-classic/AmiModRadio/
OBJECTSDIR = o/vbcc-classic/release/
endif
# Secondary paths
EXE = $(EXEDIR)AmiModRadio
DATADIR = $(EXEDIR)data/
ICONSDIR = $(EXEDIR)icons/
IMAGESDIR = $(EXEDIR)images/
MODULESDIR = $(EXEDIR)modules/
# (Re)Source files
SOURCES = $(wildcard *.c)
OBJECTS = $(addprefix $(OBJECTSDIR), $(SOURCES:.c=.o))
DATA = $(addprefix $(DATADIR), $(shell find data/ -mindepth 1 -maxdepth 1 -printf "%f\n" | sed 's/ /?/g'))
ICONS = $(addprefix $(ICONSDIR), $(shell find icons/ -mindepth 1 -maxdepth 1 -printf "%f\n" | sed 's/ /?/g'))
IMAGES = $(addprefix $(IMAGESDIR), $(shell find images/ -mindepth 1 -maxdepth 1 -printf "%f\n" -type d | sed 's/ /?/g'))
# compiler and linker
CC = vbcc:bin/vc
LD = vbcc:bin/vc
# Because Make does not support spaces properly...
space :=
space +=
replaceQuestionBySpace = $(subst ?,$(space),$1)
replaceSpaceByQuestion = $(subst $(space),?,$1)
# ----------------------------------------
# target 'all' (default target, for debug)
all : CFLAGS += -DFORTIFY
all : $(EXEDIR)\
$(OBJECTSDIR)\
$(EXE)\
data\
images
# target 'dist' for release
dist : mostlyclean\
$(EXEDIR)\
$(OBJECTSDIR)\
$(EXE)\
data\
icons\
images\
modules\
$(EXEDIR:/=).lha
# target 'mostlyclean'
mostlyclean :
-rm $(EXE)
-rm $(OBJECTSDIR)*
# target 'clean'
clean : mostlyclean
-rm $(DATADIR)*
-rm $(ICONSDIR)*
-rm $(IMAGESDIR)*
-rm $(MODULESDIR)*
# ----------------------------------------
# Directories
$(EXEDIR) :
mkdir "$#"
$(OBJECTSDIR) :
mkdir "$#"
# Objects and executable
$(OBJECTS) : $(OBJECTSDIR)%.o : %.c
$(CC) $(shell vbccprefs) $(CFLAGS) -c $< -o $#
$(EXE) : $(OBJECTS)
$(LD) $(shell vbccprefs) -o $(EXE) $(OBJECTS)
# Data
data : $(DATADIR)\
$(DATA)\
$(DATADIR) :
mkdir "$#"
$(DATA) : $(DATADIR)% : $(wildcard data/%)
cp -f -R "$(call replaceQuestionBySpace,data/$*)" "$(call replaceQuestionBySpace,$#)"
# Icons
icons : $(ICONSDIR)\
$(ICONS)\
$(EXE).info\
$(EXEDIR:/=).info
$(ICONSDIR) :
mkdir "$#"
$(ICONS) : $(ICONSDIR)% : $(wildcard icons/%)
cp -f -R "$(call replaceQuestionBySpace,icons/$*)" "$(call replaceQuestionBySpace,$#)"
$(EXE).info :
cp -f -R "$(ICONSDIR)AmiModRadio2.tool.info" "$#"
$(EXEDIR:/=).info :
cp -f -R "$(ICONSDIR)AmiModRadio3.drawer.info" "$#"
# Images
images : $(IMAGESDIR)\
$(IMAGES)\
$(IMAGESDIR) :
mkdir "$#"
$(IMAGES) : $(IMAGESDIR)% : $(wildcard images/%)
cp -f -R "$(call replaceQuestionBySpace,images/$*)" "$(call replaceQuestionBySpace,$#)"
# Modules
modules : $(MODULESDIR)
$(MODULESDIR) :
mkdir "$#"
# LHA archive of 'dist'
$(EXEDIR:/=).lha : PARENTDIR = $(dir $(patsubst %/,%,$(EXEDIR)))
$(EXEDIR:/=).lha : EXENAME = $(notdir $(patsubst %/,%,$(EXEDIR)))
$(EXEDIR:/=).lha :
rm -f RAM:$(EXENAME).lha
/C/LHA -r -e a RAM:$(EXENAME).lha $(PARENTDIR) $(EXENAME).info $(EXENAME)/*

Related

make: Nothing to be done for 'all'. in Omnet

After Installng Omnetpp 5.5.1 in Ubuntu 18.04 ,For any folder in Omnetpp, make command is not making any sense.
As it showing the following message:
make: Nothing to be done for 'all'.
Even suggested methods on Internet are not working in my case.Please help.
My makefile is following for Aloha Folder.
#
# OMNeT++/OMNEST Makefile for aloha
#
# This file was generated with the command:
# opp_makemake -f --deep
#
# Name of target to be created (-o option)
TARGET = aloha$(D)$(EXE_SUFFIX)
TARGET_DIR = .
# User interface (uncomment one) (-u option)
USERIF_LIBS = $(ALL_ENV_LIBS) # that is, $(TKENV_LIBS) $(QTENV_LIBS) $(CMDENV_LIBS)
#USERIF_LIBS = $(CMDENV_LIBS)
#USERIF_LIBS = $(TKENV_LIBS)
#USERIF_LIBS = $(QTENV_LIBS)
# C++ include paths (with -I)
INCLUDE_PATH =
# Additional object and library files to link with
EXTRA_OBJS =
# Additional libraries (-L, -l options)
LIBS =
# Output directory
PROJECT_OUTPUT_DIR = out
PROJECTRELATIVE_PATH =
O = $(PROJECT_OUTPUT_DIR)/$(CONFIGNAME)/$(PROJECTRELATIVE_PATH)
# Object files for local .cc, .msg and .sm files
OBJS = $O/Host.o $O/Server.o
# Message files
MSGFILES =
# SM files
SMFILES =
#------------------------------------------------------------------------------
# Pull in OMNeT++ configuration (Makefile.inc)
ifneq ("$(OMNETPP_CONFIGFILE)","")
CONFIGFILE = $(OMNETPP_CONFIGFILE)
else
ifneq ("$(OMNETPP_ROOT)","")
CONFIGFILE = $(OMNETPP_ROOT)/Makefile.inc
else
CONFIGFILE = $(shell opp_configfilepath)
endif
endif
ifeq ("$(wildcard $(CONFIGFILE))","")
$(error Config file '$(CONFIGFILE)' does not exist -- add the OMNeT++ bin directory to the path so that opp_configfilepath can be found, or set the OMNETPP_CONFIGFILE variable to point to Makefile.inc)
endif
include $(CONFIGFILE)
# Simulation kernel and user interface libraries
OMNETPP_LIBS = $(OPPMAIN_LIB) $(USERIF_LIBS) $(KERNEL_LIBS) $(SYS_LIBS)
COPTS = $(CFLAGS) $(IMPORT_DEFINES) $(INCLUDE_PATH) -I$(OMNETPP_INCL_DIR)
MSGCOPTS = $(INCLUDE_PATH)
SMCOPTS =
# we want to recompile everything if COPTS changes,
# so we store COPTS into $COPTS_FILE and have object
# files depend on it (except when "make depend" was called)
COPTS_FILE = $O/.last-copts
ifneq ("$(COPTS)","$(shell cat $(COPTS_FILE) 2>/dev/null || echo '')")
$(shell $(MKPATH) "$O" && echo "$(COPTS)" >$(COPTS_FILE))
endif
#------------------------------------------------------------------------------
# User-supplied makefile fragment(s)
# >>>
# <<<
#------------------------------------------------------------------------------
# Main target
all: $(TARGET_DIR)/$(TARGET)
$(TARGET_DIR)/% :: $O/%
#mkdir -p $(TARGET_DIR)
$(Q)$(LN) $< $#
ifeq ($(TOOLCHAIN_NAME),clangc2)
$(Q)-$(LN) $(<:%.dll=%.lib) $(#:%.dll=%.lib)
endif
$O/$(TARGET): $(OBJS) $(wildcard $(EXTRA_OBJS)) Makefile $(CONFIGFILE)
#$(MKPATH) $O
#echo Creating executable: $#
$(Q)$(CXX) $(LDFLAGS) -o $O/$(TARGET) $(OBJS) $(EXTRA_OBJS) $(AS_NEEDED_OFF) $(WHOLE_ARCHIVE_ON) $(LIBS) $(WHOLE_ARCHIVE_OFF) $(OMNETPP_LIBS)
.PHONY: all clean cleanall depend msgheaders smheaders
.SUFFIXES: .cc
$O/%.o: %.cc $(COPTS_FILE) | msgheaders smheaders
#$(MKPATH) $(dir $#)
$(qecho) "$<"
$(Q)$(CXX) -c $(CXXFLAGS) $(COPTS) -o $# $<
%_m.cc %_m.h: %.msg
$(qecho) MSGC: $<
$(Q)$(MSGC) -s _m.cc -MD -MP -MF $O/$(basename $<)_m.h.d $(MSGCOPTS) $?
%_sm.cc %_sm.h: %.sm
$(qecho) SMC: $<
$(Q)$(SMC) -c++ -suffix cc $(SMCOPTS) $?
msgheaders: $(MSGFILES:.msg=_m.h)
smheaders: $(SMFILES:.sm=_sm.h)
clean:
$(qecho) Cleaning $(TARGET)
$(Q)-rm -rf $O
$(Q)-rm -f $(TARGET_DIR)/$(TARGET)
$(Q)-rm -f $(TARGET_DIR)/$(TARGET:%.dll=%.lib)
$(Q)-rm -f $(call opp_rwildcard, . , *_m.cc *_m.h *_sm.cc *_sm.h)
cleanall:
$(Q)$(MAKE) -s clean MODE=release
$(Q)$(MAKE) -s clean MODE=debug
$(Q)-rm -rf $(PROJECT_OUTPUT_DIR)
# include all dependencies
-include $(OBJS:%=%.d) $(MSGFILES:%.msg=$O/%_m.h.d)
This aforementioned file is missing some information like c++ INCLUDE_PATH and EXTRA_OBJS and LIBS.Is this the reason for not being run?Please Help.
The makefile says that 'Nothing to be done' because the executable is present and up to date, so it is indeed nothing to be done. This is not an error.
As you have indicated, you can execute ./aloha and then that throws a runtime error. This is NOT related to the build process.

compiling *.C and *.S sources from same directory 'make'

I have been working with a project that only compiles C sources but I've found I need some assembler too, I'm reticent to inline the asm code in a C file as GCC may not interpret it correctly.
My predecesor created the makefile for the project (apologies, it's fairly long):
# Compiler and options
CC := sparc-rtems-gcc
# The application software binary
TARGET := icu_asw
# Source and build directories
SRCDIR := src
BUILDDIR := obj
TARGETDIR := bin
HDSWROOT := ../../hdsw
BSWTOOLS := ../../bsw/sw/tools
SRCEXT := c
DEPEXT := d
OBJEXT := o
MRAMEXT := img.elf
# Flags, libraries and includes
CFLAGS := -std=gnu99 -Wall -Wextra -g
LIBDRV := $(HDSWROOT)/lib/libdrv.a
INCFLAGS := -I$(HDSWROOT)/include -I$(HDSWROOT)/osal/rtems
# Debug flags
DEBUGFLAGS = -DLOGERROR=1 -DLOGWARN=1 -DLOGDEBUG=1 -DLOGINFO=1 -DMAKECHECKS=1
NODEBUGFLAGS = -DLOGERROR=1 -DLOGWARN=0 -DLOGDEBUG=0 -DLOGINFO=0 -DMAKECHECKS=1
#-----------------------------------------------------------------------
# Build instructions
#-----------------------------------------------------------------------
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))
# Default make
all: $(TARGET)
# Remake
remake: cleaner all
# Clean only objects
clean:
#$(RM) -rf $(BUILDDIR)
# Full clean (objects and binaries)
cleaner: clean
#$(RM) -rf $(TARGETDIR)
# Pull in dependency info for *existing* .o files
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
# Link (uses an order-only prerequisite for the directories so that they
# don't affect the use of the $^)
$(TARGET): $(OBJECTS) | directories
$(CC) -o $(TARGETDIR)/$(TARGET) $^ $(LIBDRV)
# Make the build and target directories
directories:
#mkdir -p $(TARGETDIR)
#mkdir -p $(BUILDDIR)
# Compile
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) $(INCFLAGS) $(NODEBUGFLAGS) -c -o $# $<
#$(CC) $(CFLAGS) $(INCDEP) -MM $(SRCDIR)/$*.$(SRCEXT) > $(BUILDDIR)/$*.$(DEPEXT)
#cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
#sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
#sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
#rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
# Non-File Targets
.PHONY: all remake clean cleaner
I want to also bring in and compile two .S files, so, I edited the following line
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT) -or -name *.$(ASMEXT))
To bring in the .S files, then I edited the OBJECTS to also include the ASM sources ("*.S")
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)),$(SOURCES:.$(ASMEXT)=.$(OBJEXT)))
But when recompiling with 'make all' I'm getting:
$ make all
make: *** No rule to make target `obj/asi_access.S', needed by `icu_asw'. Stop.
I don't suppose someone could spot where I am going wrong? I think I have not correctly added to the OBJECTS line!
Thanks
The expression $(var:.ext1=.ext2) does not filter by .ext1, i.e.
$(SOURCES:.$(SRCEXT)=.$(OBJEXT)) $(SOURCES:.$(ASMEXT)=.$(OBJEXT))
gives for a test source list the following result
a.o b.o c.S a.c b.c c.o
I.e. you duplicated your files and you have source files in the OBJECTS definition.
The following would be a correct approach:
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%, \
$(patsubst %.$(SRCEXT),%.$(OBJEXT), \
$(patsubst %.$(ASMEXT),%.$(OBJEXT),$(SOURCES)) \
) \
)
UPDATE: you should consider to use 2 separate object lists, so that you can apply different rules for them, e.g.
SOURCES_C := $(filter %.$(SRCEXT),$(SOURCES))
OBJECTS_C := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES_C:%.$(SRCEXT)=%.$(OBJEXT)))
SOURCES_ASM := $(filter %.$(ASMEXT),$(SOURCES))
OBJECTS_ASM := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES_ASM:%.$(ASMEXT)=%.$(OBJEXT)))
$(OBJECTS_C): $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)
.... C compiler recipe ....
$(OBJECTS_ASM): $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(ASMEXT)
.... assembler recipe ....
$(TARGET): $(OBJECTS_C) $(OBJECTS_ASM) | directories

Variable substitution in Makefile target dependency

I have a Makefile with targets that have associated dependencies. So I use lookup table like:
APPS = a b c
dependency.lookup.a := x
dependency.lookup.b := y
dependency.lookup.c := z
$(APPS): %: path/$(dependency.lookup.%).datafile
do something with $(dependency.lookup.$#)
This makefile gives me error.
*** No rule to make target 'path/.datafile'
Constraints: Only MinGW. can't use shell/MSYS. Also support FreeBSD.
This requires using Secondary Expansion feature:
.SECONDEXPANSION:
$(APPS): %: path/$$(dependency.loopup.$$*).datafile
#echo "$# depends on $^"
%.datafile : # Create one on demand for testing.
mkdir -p ${#D}
touch $#
Outputs:
mkdir -p path/
touch path/x.datafile
a depends on path/x.datafile
Alternatively, use regular dependencies:
a : path/x.datafile
b : path/y.datafile
c : path/z.datafile
$(APPS): % :
#echo "$# depends on $^"
The top 3 lines only add dependencies, the rule is specified separately. The output is the same.
I had the same problem but with rather long names. I didn't want to repeat them (in APPS = ...), so I used a generated auxiliary makefile.
Makefile:
all: build
include deps.mk
deps.mk: deps.txt deps.sh
./deps.sh <$< >$#
build: $(DEPS)
echo "DEPS are up-to-date." # or whatever
deps.sh:
#!/bin/bash
echo "# This file is generated by $0"
echo "DEPS ="
while read -r dst src; do
echo
echo "DEPS += $dst"
echo "$dst: $src"
echo -e '\t''cp $< $#' # or whatever
done
deps.txt (now only this file needs to be updated for new dependencies):
a x
b y
c z

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