1
votes

Tried to get GNU make 3.81 Built-in Function to work but kept getting an error message.

I built a simple makefile:

FOO=bar

$(info $(FOO) $(origin FOO))

$(firstword $(origin FOO))

and ran it. The first function works but second will not.

Error message is:

...

$ make -d

GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This program built for i686-pc-linux-gnu

Reading makefiles...

Reading makefile `makefile'...

bar file

makefile:6: *** missing separator. Stop.

...

First two functions work correctly so why is this happening? Am I not seeing something obvious or is this $(firstword) function not supported in this version of make? Thanks for any help.

2
The above example makefile is straight out of the book "GNU Make Book" by John Graham-Cumming. It does not need a target or the use of tabs or be in a rule to have Make build it. An example which I just found works: MY_LIST = a program for directed compilation $(info The first word is $(firstword $(MY_LIST))) This solves part of my question that $(firstword ...) function does actually work. So the real question is "Why is the function $(origin ..) not outputting a compliant string?"timoh
Using make functions outside of recipes is perfectly legit, to the contrary to what suggest the answers. Since you don't have any target, make should complain as make: *** No targets. Stop.. It should however still print the $(info ...) message though.... Could you try to add an empty target at the end, i.e. just add the line all: at the end?jmon12

2 Answers

1
votes

For the most part, a make file looks like one or more of these blocks:

target: [depends-on]...
        command to build
        another command

Where the command lines start with a tab. Your error is complaining about finding 2 consecutive lines that look like target lines.

I've never seen the book you speak of, but either it is wrong or you are reading it wrong. Try this:

FOO=bar

all:
        $(info $(FOO) $(origin FOO))
        echo '<' $(firstword $(origin FOO)) '>' 

You need the echo on the last line because firstword is an ordinary substitution function, while info works more like a command.

I put the angle brackets on the firstword line just to show what was going on where.

Again, note that indented lines on Makefiles use tabs not spaces.

0
votes

The firstword function is a text manipulation function. It takes text as its input, and returns text as its output. It does not write any messages or error output.

As such, when you call it, you are using it to build a makefile. Makefiles have a special syntax, just like any other programming language. When you put text into a makefile, it has to be structured in a particular way - you have to make a statement, or define a variable, or something.

For example, this is what a 'build rule' looks like:

output: input
    rule to produce output from input

You put a word into the makefile (the result of $(firstword)), so make assumes you are doing something - defining a variable or specifying a build rule. But you didn't follow up with any other words. Basically, your make program has a syntax error. :(