LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 04-24-2006, 01:41 AM   #1
George2
Member
 
Registered: Oct 2003
Posts: 354

Rep: Reputation: 30
how to print variable value in Makefile?


Hello everyone,


I want to print variable value of Makefile, but it seems that simple echo command is not working.

This is my Makefile,

--------------------
Foo=newdir
echo $Foo
--------------------

when I execute make, it prints out the following error message,

--------------------
Makefile:2: *** missing separator. Stop.
--------------------

I am using Red Hat Linux 9.0. Does anyone know what is the correct approach to print out the value of a variable?


thanks in advance,
George
 
Old 04-24-2006, 02:25 AM   #2
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
It would be extremely beneficial to read the documentation on make. It's very thorough and not too terribly technical in the language it uses. I say that because the Makefile you present demonstrates a basic mistake.

Makefiles aren't like shell scripts. You need to create targets (objects that make tries to create). The make command only looks for commands to execute related to a specific target, and also requires the command to be indented with a tab character as the first character on the line. The documentation describes it a little better. To give you a Makefile that will accomplish what you want, use this:
Code:
Foo=newdir

.PHONY: print_vars

print_vars:
echo $(Foo)
 
Old 04-24-2006, 03:54 AM   #3
George2
Member
 
Registered: Oct 2003
Posts: 354

Original Poster
Rep: Reputation: 30
Dark_Helmet.


Quote:
Originally Posted by Dark_Helmet
It would be extremely beneficial to read the documentation on make. It's very thorough and not too terribly technical in the language it uses. I say that because the Makefile you present demonstrates a basic mistake.

Makefiles aren't like shell scripts. You need to create targets (objects that make tries to create). The make command only looks for commands to execute related to a specific target, and also requires the command to be indented with a tab character as the first character on the line. The documentation describes it a little better. To give you a Makefile that will accomplish what you want, use this:
Code:
Foo=newdir

.PHONY: print_vars

print_vars:
echo $(Foo)
Thank you for your great reply! I would like to read through the Makefile document. But I do not know which document do you mean. Could you provide an URL please?

Another question is that, what is the use of .PHONY target? I think the following Makefile will work the same,

Code:
Foo=newdir
print_vars:
echo $(Foo)

regards,
George
 
Old 04-24-2006, 10:27 AM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
The ".PHONY" tag is a special "target" that tells the Makefile there are no dependencies to check against. In short, any target listed as a phony will always execute the commands for the target no matter what. Contrast that behavior with a normal target (one with .c or .h file dependencies) where the commands to create the target are only executed if one or more of the dependencies has changed.

The documentation I was referring to is located here:
Make manual
 
Old 04-25-2006, 02:01 AM   #5
George2
Member
 
Registered: Oct 2003
Posts: 354

Original Poster
Rep: Reputation: 30
Thanks Dark_Helmet,


Quote:
Originally Posted by Dark_Helmet
The ".PHONY" tag is a special "target" that tells the Makefile there are no dependencies to check against. In short, any target listed as a phony will always execute the commands for the target no matter what. Contrast that behavior with a normal target (one with .c or .h file dependencies) where the commands to create the target are only executed if one or more of the dependencies has changed.

The documentation I was referring to is located here:
Make manual
I still do not quite understand what do you mean "no dependencies to check against". Do you mean no need to check whether the dependencies have changed? Or also including other situations to check?


regards,
George
 
Old 04-25-2006, 02:28 AM   #6
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
No dependencies to check for modification.

When make is invoked, it compares the timestamp for the target's last modification against the timestamps of the target's dependencies. If the target's modification timestamp is the most recent, then the target is "up to date" and make will not perform any commands for the target. If, however, one (or more) of the target's dependencies has a more recent modification timestamp than the target itself, the target needs o be updated to reflect the changes made since the last time make was run for that target.

So, what's the timestamp for a non-existent target? When "make print_vars" is issued, we have no file representing our up-to-date target. The commands do not create a file named print_vars. So there's nothing for make to get a timestamp from. Not only that, but the print_vars target has no dependencies either. So make couldn't even look at those timestamps. So what should make do? I think the documentation says that in this case, make will do nothing for the target. The makefile needs to specify ".PHONY" to tell make to ignore its normal timestamp-check and execute the commands regardless. It's the same concept behind the "make clean" target found in many source code tarballs. The "clean" target does not create a "clean" file -- the commands are meant to accomplish the side-effect of deleting all the object files and executables for the project (to allow a from-scratch recompile).
 
Old 04-25-2006, 04:47 AM   #7
George2
Member
 
Registered: Oct 2003
Posts: 354

Original Poster
Rep: Reputation: 30
Thanks Dark_Helmet,


Quote:
Originally Posted by Dark_Helmet
No dependencies to check for modification.

When make is invoked, it compares the timestamp for the target's last modification against the timestamps of the target's dependencies. If the target's modification timestamp is the most recent, then the target is "up to date" and make will not perform any commands for the target. If, however, one (or more) of the target's dependencies has a more recent modification timestamp than the target itself, the target needs o be updated to reflect the changes made since the last time make was run for that target.

So, what's the timestamp for a non-existent target? When "make print_vars" is issued, we have no file representing our up-to-date target. The commands do not create a file named print_vars. So there's nothing for make to get a timestamp from. Not only that, but the print_vars target has no dependencies either. So make couldn't even look at those timestamps. So what should make do? I think the documentation says that in this case, make will do nothing for the target. The makefile needs to specify ".PHONY" to tell make to ignore its normal timestamp-check and execute the commands regardless. It's the same concept behind the "make clean" target found in many source code tarballs. The "clean" target does not create a "clean" file -- the commands are meant to accomplish the side-effect of deleting all the object files and executables for the project (to allow a from-scratch recompile).
Thank you very much for your great reply! I have also taken reference to some Makefile samples. I think your option is that, the .PHONY target should be used in the situation when there is no existing files to check timestamp (for some special case), is that correct? But I found that in some samples on the internet, .PHONY target is defined the same as the default "all" target, like

.PHONY: all

I think it is not the case you mentioned that there is no existing file to check timestamp.

Another question is that, what do you mean "accomplish the side-effect of deleting all the object files and executables for the project"?


regards,
George
 
Old 04-25-2006, 08:00 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,290

Rep: Reputation: 174Reputation: 174
Try:
Code:
FOO = newdir

help:
<TAB>echo FOO = ${FOO}
make help


make -pns | grep FOO

Last edited by bigearsbilly; 04-25-2006 at 08:02 AM.
 
Old 04-25-2006, 08:40 AM   #9
George2
Member
 
Registered: Oct 2003
Posts: 354

Original Poster
Rep: Reputation: 30
Thanks bigearsbilly,


Quote:
Originally Posted by bigearsbilly
Try:
Code:
FOO = newdir

help:
<TAB>echo FOO = ${FOO}
make help


make -pns | grep FOO
Why use make -pns? I have tried that make help also works.


regards,
George
 
Old 04-25-2006, 09:20 AM   #10
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,290

Rep: Reputation: 174Reputation: 174
make -pns (chortle) prints out variables and macros.

for example I have a messy tcl script for evaluating all variables
using make -pns

so for a makefile:
Code:
AA = ${PWD}
AAA = ${AA}

all:
I get:
Code:
billym.primadtpdev>makelook| grep AAA
AAA =  ${AA}
AAA =   ${PWD}
AAA =    /export/home/billym/bin
Code:
#!/bin/sh
# \
exec tclsh "$0" "$*"

# attempt to display all macro expansions
# invoked in a makefile

set macro_list ""

puts $argc
foreach nm [ array names $argv ] {
puts "$nm"
}


set infile [ open "|make -pns" r ];


while { [gets $infile line] != -1 } {
    if { [ regexp -- {^ *([a-zA-Z0-9_]*) *\=(.*)} $line dummy var value ]  } {
 set macro_list [concat $macro_list $var ]
 set $var $value
 }
}



foreach nm $macro_list {

    set val [ set $nm ]
    puts "$nm = $val"


    set newval " "
    while { [regexp {[^ ]*} $val dummy]  } {

 regsub -all {[)(]} $val {} val

 if { [catch  {set newval [ subst $val]}  ] } {
  set newval $val
     }

 if { $val == $newval } break 
 puts "$nm = $newval"
 set val $newval
 ### break

    }; ### while loop

}; ### foreach macro
 
Old 04-26-2006, 02:11 AM   #11
George2
Member
 
Registered: Oct 2003
Posts: 354

Original Poster
Rep: Reputation: 30
Thanks bigearsbilly,


Quote:
Originally Posted by bigearsbilly
make -pns (chortle) prints out variables and macros.

for example I have a messy tcl script for evaluating all variables
using make -pns

so for a makefile:
Code:
AA = ${PWD}
AAA = ${AA}

all:
I get:
Code:
billym.primadtpdev>makelook| grep AAA
AAA =  ${AA}
AAA =   ${PWD}
AAA =    /export/home/billym/bin
Code:
#!/bin/sh
# \
exec tclsh "$0" "$*"

# attempt to display all macro expansions
# invoked in a makefile

set macro_list ""

puts $argc
foreach nm [ array names $argv ] {
puts "$nm"
}


set infile [ open "|make -pns" r ];


while { [gets $infile line] != -1 } {
    if { [ regexp -- {^ *([a-zA-Z0-9_]*) *\=(.*)} $line dummy var value ]  } {
 set macro_list [concat $macro_list $var ]
 set $var $value
 }
}



foreach nm $macro_list {

    set val [ set $nm ]
    puts "$nm = $val"


    set newval " "
    while { [regexp {[^ ]*} $val dummy]  } {

 regsub -all {[)(]} $val {} val

 if { [catch  {set newval [ subst $val]}  ] } {
  set newval $val
     }

 if { $val == $newval } break 
 puts "$nm = $newval"
 set val $newval
 ### break

    }; ### while loop

}; ### foreach macro
Your reply is great! But I think I am talking about using Makefile to build C/C++ applications, what is the relationship of your tcl script with my topic?


regards,
George
 
Old 04-26-2006, 07:17 AM   #12
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,290

Rep: Reputation: 174Reputation: 174
printing variables, maybe
 
Old 04-27-2006, 05:12 AM   #13
George2
Member
 
Registered: Oct 2003
Posts: 354

Original Poster
Rep: Reputation: 30
Thanks bigearsbilly,


Quote:
Originally Posted by bigearsbilly
printing variables, maybe
I am wondering why using so complex a sample to print out variables. What points this sample want to prove and illustrate? Could you provide a simple and clear sample please? :-)


regards,
George
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl wont print my Variable!!! socceroos Programming 10 03-15-2006 05:04 PM
Getting PHP to print variable value on a webpage tangle Programming 9 02-07-2006 02:39 PM
Shell Variable available within Samba "print command" thibert Linux - Networking 0 12-12-2005 01:02 PM
Print a part of variable/string p0tw0r Linux - Newbie 1 04-07-2005 02:49 PM
how to get (makefile -f makefile )output into the textview widget in Pygtk sailu_mvn Programming 3 02-28-2005 03:57 AM


All times are GMT -5. The time now is 12:11 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration