Write a Makefile to compile .tex to .pdf - makefile

The simple process on shell script might be like this:
1 #!/bin/sh
2
3 latex --verbose manual.tex
4 dvips manual.dvi
5 ps2pdf manual.ps
6 rm manual.{aux,log,ps,dvi}
There are 3 step to convert from .tex to pdf:
.tex -> .dvi -> .ps -> .pdf
To use a Makefile what have i tried?
1 FILENAME = manual
2 $(FILENAME).pdf: $(FILENAME).ps
3 ps2pdf $(FILENAME).ps
4
5 $(FILENAME).ps: $(FILENAME).dvi
6 dvips $(FILENAME).dvi
7
8 $(FILENAME).dvi: $(FILENAME).tex
9 latex --verbose $(FILENAME).tex
This Makefile can not be success when i run make at first time i will get these file
manual.aux ,manual.dvi, manual.log
and error message is
...
l.36 \includegraphics[width=4in]{a.eps} // this error from latex
...
make: *** [manual.dvi] Error 1 // this error from Makefile
...
and if i run it again finally i will get .ps and .pdf.
Note that only one case this Makefile can work well is i have to fix latex's error first then run make. on this way i will can get .pdf without any error.
And further request for a Makefile i also want to clean up all the files the rest are only .tex and .pdf but it's not yet implemented.
Please help me to improve my code.

From what I can see, you have a benign error from latex. To handle such a situation, GNU Make uses the - prefix in front of the recipe line:
-latex --verbose $(FILENAME).tex
and now the original error will be ignored as you like, and the whole thing should work.

Related

makefile for metapost: how to compile file-N.pdf

I want to let makefile manage the compilation of figures with metapost.
The source file is file.mp. This generates .mps files file.1, file.2 etc. that are then converted to file-1.pdf, file-2.pdf etc.
Here are my rules:
export TEX = latex
%: %.1
mptopdf $*
%.1: %.mp
mpost $*
So that when I run make file it creates all the files.
However, I am not satisfied with this solution. Namely, I'd like to be able to let only one of the files be compiled (say file-2.pdf) by entering make file-2.
Unfortunately, I don't know how to write the rule for this, although I suspect it might be trivial.
I thought the problem could be solved by extracting the number from the file name given in the command line (i.e. extract 2 from file-2) but it is not clear to me how to do it either.

Makefile:1: *** missing separator. Stop error when using Make with a config file with no tabs or spaces

I have seen this question and has read its many answers. I understand that this problem usually (always??) appears because of a mistake in using tabs vs spaces in Makefiles. So far that is the general case.
In my case, I have found the error in the title but not when doing make with a Makefile I suspect.
I do:
make a_configuration_file
and I get
Makefile:1: *** missing separator. Stop.
I suppose this "1" means that the error is occurring in the first line of the file, right?
This a_configuration_file is actually a generated file and the first lines are copied here :
#
# Automatically generated file; DO NOT EDIT.
# Ambarella SDK Configuration
#
CONFIG_THREADX=y
CONFIG_BOOT_CORE_SRTOS=0
So my questions for my particular case are:
The "1" refers to the comment line "#"? or the CONFIG_THREADX line?
This configuration file is not using Tabs. So what could be the problem?
EDIT:
Robert tells me that the problem could be the end-of-line. I checked with cat -A a_configuration_file and it seems there are no \r characters (I ve had problems with this before so I learned how to check for end-of-line chars)
Wander Nauta tells me the problem is in the Makefile. Which Makefile should I check? Right now there is a Makefile in the directory from where I call make and it is like this
build/Makefile
no tabs or spaces
I also did cat -A Makefile and I got
build/Makefileroot#themachine.....
If you are wondering what is that, is just that it seems that the Makefile does not have an end of the line at the end, so the cat command prints the contents and the rest (root#themachine...) is just the normal line in the command line
EDIT2:
I think I am close to finding the error.
Originally the "Makefile" was a link as in
ls ./ -l
lrwxrwxrwx 1 1133 543 13 Mar 18 Makefile -> build/Makefile
However now it is just a plain text file
ls ./ -l
-rw------- 1 11250 10513 14 Jul 6 Makefile
Somehow in the linux-windows-linux transference the link condition got lost
In my case, I have found the error in the title but not when doing make with a Makefile I suspect.
The error in the title specifies the name of the file in which the error is encountered: Makefile. Thus, your suspicion about "not when doing so with a Makefile" is unfounded. Although it is possible to run make without a makefile, and doing so can even be advantageous, make will always read a makefile if it can find one by one of the default names it looks for.
Moreover, though it may not be obvious in this case, the name given in the message is not just a base name but a (relative) path to the file. It is therefore complaining about a file named Makefile in make's working directory.
Right now there is a Makefile in the directory from where I call make
and it is like this
build/Makefile
no tabs or spaces I also did cat -A Makefile and I got
build/Makefileroot#themachine.....
Those two claims do not appear to be consistent with each other. In any case, however, neither one attributes valid makefile content to the makefile in question. This is likely the cause of the error message, which would then be a bit misleading.
It looks like you may be trying to have one makefile specify that another make be run in the build/ directory -- a so-called "recursive make". There are a couple of variations on how that is done, and they differ slightly in effect, but here's a guess at what you might be after for that top-level Makefile:
all:
$(MAKE) -C build
Of course, that second line needs to be indented with a leading tab, not spaces.
That will cause the top-level make run to trigger a second make run with the build/ directory as the second's working directory.

Writing assembly code for raspberry Pi, MinGW error

I am following this tutorial and I have gotten to the point where I need to 'make' compiled image to get it into pi, but I am getting following error:
mkdir build/
The syntax of the command is incorrect.
Makefile:57: recipe for target 'build/' failed
mingw32-make: *** [build/] Error 1
The makefile is available here in the template. Lines 56 + 57 look like this:
$(BUILD):
mkdir $#
Can anyone tell me what's wrong and how to fix it? I am new to this and following the step by step guide :/ Thank you!
Thanks to igagis' coment I have discovered what the problem was that: mkdir build/ is incorrect command because of the slash sign '/'.
In the make file, the variable target is defined as: BUILD = build/ because it is later used as a path. I fixed line 57 as following:
$(BUILD):
mkdir build
and the code now compiles as intended.

make error: "make[1]: *** [directories] Error 1"

When I try to run "make all" on a makefile with some complexity I get this errors:
C:\BITCLOUD\BitCloud_PS_SAM3S_EK_1_10_0\BitCloud_PS_SAM3S_EK_1_10_0\Applications\ZAppSi\Dem o\SEDevice>make all
make -C makefiles/PC -f Makefile_PC_Gcc all APP_NAME=DemoSE
make[1]: Entering directory
'C:/BITCLOUD/BitCloud_PS_SAM3S_EK_1_10_0/BitCloud_PS_SAM3S_EK_1_10_0/Applications/ZAppSi/Demo/SEDevice/makefiles/PC'
A sintaxe do comando está incorrecta.
make[1]: *** [directories] Error 1
make[1]: Leaving directory
'C:/BITCLOUD/BitCloud_PS_SAM3S_EK_1_10_0/BitCloud_PS_SAM3S_EK_1_10_0/Applications/ZAppSi/Demo/SEDevice/makefiles/PC'
make: *** [all] Error 2
where the line
A sintaxe do comando está incorrecta.
translated to english means: "The syntax of the command is incorrect"
I already tried to change the project to different directories, check spaces in file names, using GNU make and also use MinGW make (mingw32-make) and the result is the same with both "make". I also checked for all files that are included in the makefile and they correspond.
Im not an expert in makefiles, so Im asking for help.
What is the main problem that occurs when make throws this type of error?
It is likely not make that throws this error, but a command executed by make returns with a nonzero exit status, in this case with status 1 (due to Error 1); then the top level make stops with Error 2. Note that make by default stops as soon as a command fails.
Since the output doesn't show what command was executed, there is no way to tell what went wrong exactly.
EDIT: from the GNU make manual:
-d Print debugging information in addition to normal processing.
The debugging information says which files are being considered
for remaking, which file-times are being compared and with what
results, which files actually need to be remade, which implicit
rules are considered and which are applied---everything inter‐
esting about how make decides what to do.
--debug[=FLAGS]
Print debugging information in addition to normal processing.
If the FLAGS are omitted, then the behavior is the same as if -d
was specified. FLAGS may be a for all debugging output (same as
using -d), b for basic debugging, v for more verbose basic
debugging, i for showing implicit rules, j for details on invo‐
cation of commands, and m for debugging while remaking make‐
files.
I suggest running make --debug=j to see the commands.

Foreach Loop Not Working in Makefile: "The system cannot find the file specified"

I have a Makefile of the following content:
NUMBERS = 1 2 3 4
lib:
$(foreach var,$(NUMBERS),./a.out $(var);)
And this is the command that I run ( in the same directory as the Makefile)
make -f Makefile
But I got an error message saying that "The system cannot find the file specified".
Following the suggestion of one of the answers, I created the following file inside the same directory as the Makefile:
a.out
1.out
2.out
3.out
4.out
Now the error becomes:
./a.out 1; ./a.out 2; ./a.out 3;
./a.out 4; make (e=-1): Error -1 make:
*** [lib] Error -1
Note: I am running on Windows XP platform
The purpose of make is to create (and update) target files that depends on source files by running commands.
Here, the problem is with the command that is run. You are trying to run (through make) the command a.out but it does not exist, or is not an executable command. Try to replace a.out in your makefile by the actual executable command you want to run.
On Windows/DOS, use && instead of ; to join multiple commands on one line. You have to manually include a final command or the trailing && will throw a syntax error. Try something like:
NUMBERS = 1 2 3 4
lib:
$(foreach var,$(NUMBERS),.\a.out $(var) && ) echo.
It seems to me that the error comes because the file a.out cannot be located and not because the makefile could not be found.
Also if the name of your makefile is "Makefile" just invoking "make" is enough (without using -f option) as make by default would look for a file by names: GNUmakefile, makefile, and Makefile in that order.
Just what are you trying to do?
It seems to me that a plain script would be better suited rather than using make.
I found the answer by bta most useful, but it didn't work for me on both Windows and Linux, so I found a way to remove the final &&, which avoids the need for a no-op command that works on both platforms:
NUMBERS = 1 2 3 4
lib:
$(filter-out &&EOL, $(foreach var,$(NUMBERS), .\a.out $(var) &&)EOL)
Of course be careful of elements within your array matching &&EOL, but in my case, this isn't a problem.

Resources