Makefile failing on last file - makefile

I'm trying to use a makefile to make some tests for my other program.
DIFF=$(TXT_FILES:$(TESTS_DIR)/%.txt=$(DIFF_DIR)/%.dif), $(STDIN_FILES:$(TESTS_DIR/%.stdin=$(DIFF_DIR)%.dif)
$(DIFF_DIR)/%.dif: $(TESTS_DIR)/%.txt $(DIFF_DIR)/%.out
./03uzduotis/getfasta $< | diff $(DIFF_DIR)/$*.out - > $#
$(DIFF_DIR)/%.dif: $(TESTS_DIR)/%.stdin $(DIFF_DIR)/%.out
cat $< | ./03uzduotis/getfasta - | diff $(DIFF_DIR)/$*.out - > $#
The problem I'm having is that when I launch the makefile, it goes through all test files except the last one, citing "There is no rule to make Test1.dif required by "tests""
I have checked by removing some Test files that it indeed dies on the last file no matter which file is the last one.

Seems like these an extraneous comma in here:
DIFF=$(TXT_FILES:$(TESTS_DIR)/%.txt=$(DIFF_DIR)/%.dif), $(STDIN_FILES:$(TESTS_DIR/%.stdin=$(DIFF_DIR)%.dif)
$(DIFF) is going to look like ddir/one.dif ddir/two.dif, ddir/stdin1.dif The middle file name there really does have a comma as part of the name. Lists in Make are separated by whitespace, not commas.
I suspect your error message isn't exact, since from your example all filenames should have been prefixed with $(DIFF_DIR)/, and the comma is the error message too.
You've also got a missing ) and a missing / in the substitution $(TESTS_DIR/%.stdin=$(DIFF_DIR)%.dif. Likely part of that is a typo in your question as the unbalanced parenthesizes would cause a parse error.

Related

How can I add syntax highlighting to a make error message?

Summary
I want to manually add syntax highlighting of specific words in error messages. I tried with a pipeline to awk, but this doesn't seem to work with the entire message that is thrown by make. Can anybody help me to get the following pipeline working for make's entire error message?
make | awk '{for(i=1;i<=NF;i++){ if($i~/error/ || $i~/Built/) $i=sprintf("\033[0;36m %s \033[0;00m",$i)}; print}'
Or maybe—better still—a different approach to my
Situation (in detail)
To build my latex project, I use Cmake together with UseLATEX (github page). That way, I can simply render my document by executing make from inside a build folder. Only problem: There is no syntax highlighting for the wall of text of an error message. I need to add a minimal version of this, to work productively. (Maybe words could be highlighted globally in my terminal?)
By passing the output in a pipeline to awk (manpage)—inspired by this askubuntu post—I was able to highlight make's success message, pdflatex myfile.tex's success and error message, but not make's error message, it did not highlight the interesting parts of the long message.
By highlighting Built in the code snippet above, one can see that it does highlight when the first command make succeeds.
The problem is that I do not fully understand when the pipeline passes what. It seems that some output can get highlighted and some cannot.
Thanks for any help!
Steps needed to reproduce
To get into exactly the situation at hand, you need a project folder containing
build/
cmake/
myfile.tex
CMakeLists.txt
with cmake/ containing UseLATEX.cmake
and CMakeLists.txt reading
include(cmake/UseLATEX.cmake)
ADD_LATEX_DOCUMENT(myfile.tex)
and myfile.tex being a valid or non-valid latex document, e.g.
\documentclass{article}
\begin{document}
Some \undefined command
\end{document}
From inside the build/ folder, call cmake .., and then make, or rather the full command above.
The message is written on stderr, not on stdout. You have to handle stderr. In bash, you can:
make 2> >(do_something_with_stderr >&2) | do_something_with_stdout
Because | changes buffering, it's not always wanted in interactive programs. For interactive I prefer:
make 2> >(do_something_with_stderr >&2) >(do_something_with_stdout)
and sometimes that's one function:
some_func() { do_something; }
make 2> >(some_func >&2) >(some_func)

Building libssh project - target pattern contains no '%'

I'm trying to install libssh-0.8.5 onto Ubuntu 16.04 using the instructions from the install.readme provided. I follow every step as stated, but I get an error after executing the make command to build the project. The error is as follows:
[ 65%] Built target exec
tests/CMakeFiles/ssh_ping.dir/flags.make:8: *** target pattern contains no '%'. Stop.
CMakeFiles/Makefile2:1696: recipe for target 'tests/CMakeFiles/ssh_ping.dir/all' failed
make[1 ]: *** [tests/CMakeFiles/ssh_ping.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2
I have researched and seen that it could be a syntax error somewhere in my make file that is preventing the build to continue. I have looked at the target make file giving the problem, but cant seem to identify what is causing the error.
The flag.make file is as follows:
The problem seems to be coming from the highlighted bold line. Can anyone see what I am missing?
On StackOverflow (and most other similar sites), please cut and paste text into your questions and format them using the proper markdown facilities, rather than attaching images containing text. The latter is difficult to read and we can't cut and paste it into our answer to show where things are going wrong.
You cannot embed newlines in quoted strings, in makefiles. Make is completely line-oriented and does not parse quotes at all. So to make this:
FOO = "bar
biz"
is not considered one line assigning a value containing a newline to a variable FOO. Instead, it's considered two lines, the first of which is assigning the value "bar to variable FOO and the second of which is a syntax error since make can't parse the string baz" as a valid command.
Apparently ssh wasn't installed properly on your platform, while cmake relies on it. I am a bit surprised that cmake itself did not raise an error when generating flag.make but as I don't use cmake I do not know whether it is its normal behaviour or not.
Anyway, when cmake tried to detect your version of OpenSSH it did it by running ssh and got an error message instead of the version number it wanted. This error message got inserted in the generated flag.make Makefile. Because the second line of this error message (I could copy-paste it here if it was not in a picture in your question) has the:
a: b: c
form, make tried to interpret it as a static pattern rule but as it contains no % wildcard character, make raised a syntax error.
What happens if you try to run /usr/bin/ssh -V on the command line?

How to delete files like 'Incoming11781rKD'

I have a programme that is generating files like this "Incoming11781Arp", and there is always Incoming, and there is always 5 numbers, but there are 3 letters/upper-case/lower-case/numbers/special case _ in any way. Like Incoming11781_pi, or Incoming11781rKD.
How can I delete them using a script run from a cron job please? I've tried -
#!/bin/bash
file=~/Mail/Incoming******
rm "$file";
but it failed saying that there was no matching file or directory.
You mustn't double-quote the variable reference for pathname expansion to occur - if you do, the wildcard characters are treated as literals.
Thus:
rm $file
Caveat: ~/Mail/Incoming****** doesn't work the way you think it does and will potentially match more files than intended, as it is equivalent to ~/Mail/Incoming*, meaning that any file that starts with Incoming will match.
To only match files starting with Incoming that are followed by exactly 6 characters, use ~/Mail/Incoming??????, as #Jidder suggests in a comment.
Note that you could make your glob (pattern) even more specific:
file=~/Mail/Incoming[0-9][0-9][0-9][0-9][0-9][[:alpha:]_][[:alpha:]_][[:alpha:]_]
See the bash manual for a description of pathname expansion and pattern syntax: http://www.gnu.org/software/bash/manual/bashref.html#index-pathname-expansion.
You can achieve the same effect with the find command...
$ directory='~/Mail/'
$ file_pattern='Incoming*'
$ find "${directory}" -name "${file_pattern}" -delete
The first two lines define the directory and the file pattern separately, the find command will then proceed to delete any matching files inside that directory.

How can I debug .gitignore file handling?

I’m having lots of trouble convincing git to ignore files in my project.
Basically, sometimes it works, sometimes it just seems to ignore the .gitignore file for no obvious reason. (By “seems” I mean that there are patterns in it that look as if they should exclude something, but that something is not excluded.)
There’s a 'git check-ignore' command, but it only says which pattern matched a file. But I can’t find any option to make it say which patterns it’s found and where, nor why those patterns do not match a file.
Is there a way to do this kind of debugging?
P.S. There is a single issue which I did find, and I’m mentioning it here in case it helps others:
I was adding patterns using “echo pattern >> .gitignore”, which at least on my system results in spaces at the of the line (i.e., everything between “echo” and “>>” is echoed in the file, except for the first space character after “echo”).
Git does not trim those spaces when matching patterns, so for the command above it wouldn’t match a file named “pattern” but it would match “pattern{space}”.
I think most of my issues stem from this. Those extra spaces are hard to notice, so I’d still like a debug command that makes sure I notice them, if there is one.
Edit #1:
Yes, I did try -v. For example:
> mkdir test
> touch test/file.txt
> echo test >> .gitignore
> git check-ignore -v test/file.txt
(nothing is printed)
> echo test>> .gitignore
> git check-ignore -v test/cuc.txt
.gitignore:8:test test/cuc.txt
Note the extra space in the first echo line, which makes it enter “test[space]” as a pattern. As I mentioned, “check-ignore” tells you what matched, but it doesn’t tell you what didn’t nor why.

Makefile problem with files beginning with "#"

I have a directory "FS2" that contains the following files:
ARGH
this
that
I have a makefile with the following contents.
Template:sh= ls ./FS2/*
#all: $(Template)
echo "Template is: $(Template)"
touch all
When I run "clearmake -C sun" and the file "all" does not exist, I get the following output:
"Template is: ./FS2/#ARGH# ./FS2/that ./FS2/this"
Modifying either "this" or "that" does not cause "all" to be regenerated. When run with "-d" for debug, the "all" target is only dependent on the directory "./FS2", not the three files in the directory. I determined that when it expands "Template", the "#" gets treated as the beginning of a comment and the rest of the line is ignored!
The problem is caused by an editor that when killed leaves around files that begin with "#". If one of those files exists, then no modifications to files in the directory causes "all" to be regenerated.
Although, I do not want to make compilation dependent on whether a temporary file has been modified or not and will remove the file from the "Template" variable, I am still curious as to how to get this to work if I did want to treat the "#ARGH#" as a filename that the rule "all" is dependent on. Is this even possible?
I have a directory "FS2" that contains the following files: #ARGH# ...
Therein lies your problem. In my opinion, it is unwise using "funny" characters in filenames. Now I know that those characters are allowed but that doesn't make them a good idea (ASCII control characters like backspace are also allowed with similar annoying results).
I don't even like spaces in filenames, preferring instead SomethingLikeThis to show independent words in a file name, but at least the tools for handling spaces in many UNIX tools is known reasonably well.
My advice would be to rename the file if it was one of yours and save yourself some angst. But, since they're temporary files left around by an editor crash, delete them before your rules start running in the makefile. You probably shouldn't be rebuilding based on an editor temporary file anyway.
Or use a more targeted template like: Template:sh= ls ./FS2/[A-Za-z0-9]* to bypass those files altogether (that's an example only, you should ensure it doesn't faslely exclude files that should be included).
'#' is a valid Makefile comment char, so the second line is ignored by the make program.
Can you filter out (with grep) the files that start with # and process them separately?
I'm not familiar with clearmake, but try replacing your template definition with
Template:sh= ls ./FS2/* | grep -v '#'
so that filenames containing # are not included in $(Template).
If clearmake follows the same rules as GNU make, then you can also re-write your target using something like Template := $(wildcard *.c) which will be a little more intelligent about files with oddball names.
If I really want the file #ARGH# to contribute to whether the target all should be rebuilt as well as be included in the artifacts produced by the rule, the Makefile should be modified so that the line
Template:sh= ls ./FS2/*
is changed to
Template=./FS2/*
Template_files:sh= ls $(Template)
This works because $(Template) will be replaced by the literal string ./FS2/* after all and in the expansion of $(Template_files).
Clearmake (and GNU make) then use ./FS2/* as a pathname containing a wildcard when evaluating the dependencies, which expands in to the filenames ./FS2/#ARGH# ./FS2/that ./FS2/this and $(Template_files) can be used in the rules where a list of filenames is needed.

Resources