0

I'm trying to convert all .txt with a script to a different format.
I'm allowed to use shell commands just for the targets, but I'm not allowed to use loops...
BTW I have to use the dash interpreter.
The script is called txtConverter. It reads txt from stdin and puts the converted text (maybe markdown or other format) to stdout. So I have to read all .txt files in the current directory and comverting each by using the script to a explicit format with a different file name.
For Example if there is just 1 .txt file in the current directory, there should be 2 files after using the makefile:

1. Directory: Hallo.txt
2. using make
3. Directory: Hallo.txt
              Hallo.sh

I found something like this:

OBJ=$(patsubst %.txt, %.sh, $(wildcard *.txt))

This should look for .txt files and convert it to .sh files right?

convertToSh : $(OBJ) 
    What kind of Code?

But I need a rule to convert right?

%.txt : %.sh

The problem is I dont know how to use shell code to fill the .sh file like:

cat $< | ./txtConverter > $@

If I use $() to execute shell code it doens't work as well like:

@echo $(ls -1)

I'm new to Makefiles and I was looking in a documentary but I don't really understood how it works. I am not sure how it looks like if u put all this together in one Makefile. Thx for help!

SOLUTION FOUND:

Thx to @MadScientist and thx to A Makefile to Convert All Markdown Files to PDFs Using Pandoc

.RECIPEPREFIX = ~
OBJS=$(patsubst %.txt, %.sh, $(wildcard *.txt))
convertToSh : $(OBJS)
%.sh : %.txt
~ ./convertTxtToSh > $@ < $<

Works fine! Found .RECIPEPREFIX = ~ in the GNU Manual from @MadScientist

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
homior
  • 161
  • 1
  • 12
  • Note `.RECIPEPREFIX` was added in GNU make 4.0 so some distributions might have older versions of GNU make that don't support it. If you're satisfied with the answer don't forget to mark it accepted (click the checkmark) so people see that the question has been answered. – MadScientist Jul 03 '17 at 13:39

1 Answers1

1

The best place to go to learn about make (IMO) is the GNU Make Manual. Of course there are different variations of make and this manual discusses the GNU version, but that's probably the most common version out there.

The recipe of a rule is written in shell script syntax, so you can put the shell code directly there as the recipe.

However, a pattern rule definition is target : prerequisite. So in your case where you want to create a .sh (the target) from a .txt (the prerequisite) you'd want to write:

%.sh : %.txt
        cat $< | ./txtConverter > $@

Or to avoid the UUOC you could write:

%.sh : %.txt
        ./txtConverter > $@ < $<

Remember you must use an actual TAB character before the recipe lines. Make sure your editor doesn't replace it with spaces or something.

However this is just a template that tells make, "if you want to create foo.sh, and you have (or can figure out how to build) a foo.txt, then you can use this recipe to do it".

So next you need to tell make which .sh files you want to create. You've already got that figured out as:

OBJ=$(patsubst %.txt, %.sh, $(wildcard *.txt))

Then you need to tell make to build these. You can do it with:

convertToSh : $(OBJ)

but this rule doesn't need a recipe: there's nothing to do here because all the work is done in the pattern rule. This is just a simple way to collect all the prerequisites into one place.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • Thx a lot. How do I use the recipe if i want to call it from the bash? The convertToSh is easy to call in bash with "make convertToSh". But if I do this, the bash throws an Error (have to translate the Error to english) "there is no rule to build the target "example.sh", needed from convertToSh ". – homior Jul 03 '17 at 12:04
  • To run make you just type `make`. It will build the first explicit target in the makefile by default (that would be `convertToSh` here). Or you can explicitly run `make convertToSh` if you prefer. (FYI if you run `LANG=C make` then the messages are printed in English.) – MadScientist Jul 03 '17 at 13:33