Makefile no rule to make target index.html needed by all? - makefile

Need a fresh pair of eyes on this. Thanks in advance. Isn't the rule '%.html' ? I'm wanting to find all my wiki files and convert them with pandoc to html.
SOURCES = $(shell find $$wiki -name "*.wiki")
HTML=$(patsubst %.wiki,%.html,$(SOURCES))
all: $(HTML)
%.html: $(SOURCES)
#echo -e "Converting wiki file $# to html."

Problem - It was finding other files in directories that had files with spaces.
Solution - Restricted the search with the find command.

Related

GNU make: how to ensure pattern to match only filename without directory

I just want to copy files from other directories (before doing something). Because it's tedious to write the copy command for each file, I tried
%: ../src1/%
#echo cp $^ .
%: ../src2/%
#echo cp $^ .
all: file1 file2 file3 file4
# do something
but this doesn't work because make tries to look into ../src2/../src2/../src2/../ . . . . (I included echo for testing to prevent actual copying from happening. I keep forgetting what the "dry run" command line options is . . .)
I naïvely thought that there must be a way to force matches only to filenames that don't include directories.
Is there a way?
You can mark the "make anything" rules terminal with a double colon:
%:: ../src1/%
#echo cp $^ .
%:: ../src2/%
#echo cp $^ .
This does not answer your specific question of how to get Make to match only filenames without directories, but it does get Make to do what you want.
There is another approach that works and is closer to what you asked for: add pattern rules to satisfy Make:
../src1/%:
#: # do nothing
%: ../src1/%
#echo cp $^ .
EDIT: Or better still, us one dummy pattern rule to cover all source directories:
../%:
#: # do nothing

What's wrong with this Makefile and LaTeX?

I am trying to use the following Makefile in order to compile a LaTeX project.
# LaTeX Makefile
FILE=Tesis
all: $(FILE).pdf
.PHONY: clean
clean:
rm *.aux *.blg *.out *.bbl *.log *.dvi *.idx *.lof *.toc *.pdf
$(FILE).pdf: $(FILE).tex
$(FILE).tex: Generalidades.tex Analisis.tex Diseno.tex Construccion.tex Conclusiones.tex Tesis.bib
latex $(FILE).tex
bibtex $(FILE)
latex $(FILE)
dvipdfm $(FILE).dvi
The file Tesis.pdf doesn't exist. However after running make I get:
make: Nothing to be done for `all'
What is wrong? Thanks.
Your dependency
$(FILE).pdf: $(FILE).tex
has no rule associated with it – it's missing a sequence of indented lines which tell make how to make the PDF from the .tex file. That means it'll always be up to date.
Your second dependency, on the other hand:
$(FILE).tex: Generalidades.tex Analisis.tex ...
latex $(FILE).tex
says ‘$(FILE).tex depends on Generalidades.tex Analisis.tex ..., and to make it [ie, the .tex file] up to date, run latex’. That's not what you mean.
Try
$(FILE).pdf: $(FILE).tex Generalidades.tex Analisis.tex ...
latex $(FILE).tex
...
(By the way, if you use pdflatex then you can generate a PDF file directly from the .tex source. You'll have to use .pdf figures rather than .eps ones, but it's easy to convert .eps figures to .pdf).

Converting all files in a folder to md using pandoc on Mac

I am trying to convert an entire directory from html into markdown. The directory tree is quite tall, so there are files nested two and three levels down.
In answering this question, John MacFarlane suggested using the following Makefile:
TXTDIR=sources
HTMLS=$(wildcard *.html)
MDS=$(patsubst %.html,$(TXTDIR)/%.markdown, $(HTMLS))
.PHONY : all
all : $(MDS)
$(TXTDIR) :
mkdir $(TXTDIR)
$(TXTDIR)/%.markdown : %.html $(TXTDIR)
pandoc -f html -t markdown -s $< -o $#
Now, this doesn't seem to go inside subdirectories. Is there any easy way to modify this so that it will process the entire tree?
I don't need this to be in make. All I'm looking for is a way of getting a mirror of the initial directory where each html file is replaced by the output of running pandoc on that file.
(I suspect something along these lines should help, but I'm far from confident that I won't break things if I try to go at it on my own. I'm illiterate when it comes to GNU make).)
Since you mentioned you don't mind not using make, you can try bash.
I modified the code from this answer, use in the parent directory:
find ./ -iname "*.md" -type f -exec sh -c 'pandoc "${0}" -o "${0%.md}.pdf"' {} \;
It worked when I tested it, so it should work for you.
As per the request Any ideas how to specify the output folder? (Using html as the original file and md as the output):
find ./ -iname "*.html" -type f -exec sh -c 'pandoc "${0}" -o "./output/$(basename ${0%.html}.md)"' {} \;
I have tested this and it works for me.
Edit: As per a comment, the {} \; when used with find and the -exec option is used as a, more or less, placeholder for where the filename should be. As in it expands the filenames found to be placed in the command. The \; ends the -exec. See here for more explanation.
This is how I did it!
files=($(find ${INPUT_FOLDER} -type f -name '*.md'))
for item in ${files[*]}
do
printf " %s\n" $item
install -d ${DIR}/build/$item
pandoc $item -f markdown -t html -o ${DIR}/build/$item.html;
rm -Rf ${DIR}/build/$item
done
I've created a python script for converting all files under a folder tree which have a given suffix. It's called Pandoc-Folder. It might be useful, so I've put it on github: https://github.com/andrewrproper/pandoc-folder
You can create a settings folder and file (YAML format), and then run it like this:
python pandoc-folder.py ./path/to/book/.pandoc-folder/settings-file.yml
there is an example-book folder and matching .bat and .sh scripts for how to convert the markdown from the example-book folder into a single output file.
I hope this might be useful to someone.
John MacFarlane's answer is almost right. However, one needs to create the subfolder for pandoc, in case it doesn't exist. This is how I'd do it:
TXTDIR=sources
HTMLS=$(wildcard *.html)
MDS=$(patsubst %.html,$(TXTDIR)/%.markdown, $(HTMLS))
.PHONY : all
all : $(MDS)
$(TXTDIR)/%.markdown : %.html $(TXTDIR)
mkdir -p $(dir $#)
pandoc -f html -t markdown -s $< -o $#
This is a solution using ipython:
from pathlib import Path
files = [path for path in Path('.').rglob('*.html')]
for f in files:
!pandoc -s {str(path)} -o {path.name.replace(".html",".md")}
Note that you must execute the command inside the directory where you keep the HTML files, and your file will be saved in the same directory. In case just change the output path.

Makefile dynamic rules based on a file

I have a number of binary files (images, etc.). I need to copy some of them to an output directory as part of my build process.
The list of files that need to be copied is based on some rather complex logic, and it are generated dynamically by a Python script.
Suppose I have the following in deps.txt:
a.png
b.gif
c.mp4
How could I use a makefile to copy any necessary files to the output directory?
For example, if the output directoryalready included c.mp4 and an out-of-date version of b.gif, running the makefile would copy a.png and b.gif to the output directory (but not c.mp4).
The simplest way, if you're using GNU make, is to use an auto-generated include file, like this:
deps.txt.mk: deps.txt
cat $< | while read f; do echo "\$$(OUTPUT_DIR)/$$f: $$f ; cp $$< $$#"; done > $#
-include deps.txt.mk
If you're not using GNU make, you'll have to use recursion instead: have a rule that creates the makefile (like above), then run $(MAKE) -f deps.txt.mk to actually do the installation. Let me know if you need that example.

Using make to place message files in correct directory structure

I have an existing project where I am adding gettext support. Unfortunately, due to the project's structure and limitations, I cannot go through the recommended route of changing the project over to automake. Also unfortunately, my make-fu is pretty weak and I'm having troubles implementing rules to build my output archive:
Take all .po files in the msg subdir and run msgfmt on them to produce .mo files (in my target dir)
Put the .po files in the directory structure expected by gettext: (dir)/(locale)/LC_MESSAGES/(domainname).mo
Here's what I have so far
MSGSRC=msg/*.po
MSGOBJ=$(addprefix $(TARGET_BUILD_PATH)/$(target)/,$(MSG_SRC:.po=.mo))
$(TARGET_BUILD_PATH)/$(target)/msg/%.mo: msg/%.po
msgfmt -c $< -o $#
# Put in correct place
mkdir -p $(TARGET_BUILD_PATH)/$(target)/msg/$(*F)/LC_MESSAGES
cp $# $(TARGET_BUILD_PATH)/$(target)/msg/$(*F)/LC_MESSAGES/myapp.mo
archive: $(MSGOBJ) (other objs....)
(make the archive tarball...)
The problem with the existing code is that for some reason $(*F) comes out just * instead of the locale name (the .po files are named en_US.po, etc). It also seems incorrect because the target should be the real target, not the hacky msgfmt and copy I have. The directory structure is important because the makefile is run a few times for different cross-compiles ($(target)) and the output is archived into a tarball for installation on the devices.
I assume you can use GNU make.
First of all, let make expand the wildcards. This is important for later postprocessing:
MSGSRC=$(wildcard msg/*.po)
Now you should get lists of file names in MSGSRC and MSGOBJ. Additionally, the make manual marks $(F) as obsolete, and $ (the stem of the name) should contain just the locale. So,
mkdir -p $(TARGET_BUILD_PATH)/$(target)/msg/$*/LC_MESSAGES
should do the trick just fine, the same for the cp rule.
I do it slightly different. Here are my po files:
$ find msg -type f
msg/bg_BG.po
msg/de_DE.po
Here's the Makefile:
MSGLANGS=$(notdir $(wildcard msg/*po))
MSGOBJS=$(addprefix locale/,$(MSGLANGS:.po=.UTF-8/LC_MESSAGES/appname.mo))
gettext: $(MSGOBJS)
locale/%.UTF-8/LC_MESSAGES/appname.mo: msg/%.po
mkdir -p $(dir $#)
msgfmt -c -o $# msg/$*.po
And these are the resulting mo files:
$ find locale -type f
locale/bg_BG.UTF-8/LC_MESSAGES/appname.mo
locale/de_DE.UTF-8/LC_MESSAGES/appname.mo

Resources