Makefile variables ($@, $< ...)
Ever wondered what the funny-looking vars in the GNU Makefiles are? These two are the most common ones: $@
and @<
there are some other are special vars as well.
Here’s what these two mean, and you can look up the rest on the GNU Makefile “Automatic Variables” help page:
$@ -
is the name of the target currently being processed.
$< -
is the name of the first dependency.
1. So if you have a makefile target that looks like this:
all: clean libs app
@echo 'Building target: $@. First dependency is: $<
...
Then when you invoke ‘make all’ you will see the message:
Building target: all. First dependency is: clean.'
2. It becomes more interesting when the first dependency is a list of several values, e.g.:
OBJS := lib1/src1.c lib1/src2.c lib2/src2.c lib2/src3.c
...
myapp: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@. First dep: $<'
$(CC) $(USER_FLAGS) -o $@ $(OBJS) $(LIBS)
@echo 'Finished building target: $@'
In this case the first dependency which is the variable OBJS is evaluated. It resolves to a list of values and the first value ‘lib1/src1.c’ will be assigned to the ‘$<‘ variable.
So when making ‘myapp’ you will see the message:
Building target: myapp. First dependency is: lib1/src1.c.'
One more thing to look for, particularly if you are using echo messages to debug your make process:
Your first dependency may often be another target in the make file! In the first example (all: clean libs app) the dependencies are ‘clean’, ‘libs’ and ‘app’ and by the looks of it these are most likely other targets. Now, what I wanted point out is that if one of these targets prints a message… Then the sequence of the messages you see may not be what you expected! Or worse yet – if one of these pre-requisite targets breaks the build (!) then you may never see your message! Just keep these in mind when debugging your makefiles…
3 Responses to Makefile variables ($@, $< ...)
Leave a Reply Cancel reply
-
Categories
- Android Development
- Bash
- C programming
- dpkg/apt-get
- drupal
- Emacs
- Git
- Java
- Linux administration
- Linux device drivers
- Linux Gaming
- Linux kernel
- Linux Networking
- Linux on Windows
- Linux printing
- Linux sound and ALSA
- Package Managers
- Programming
- RPM
- Shell and environment
- Tips and tricks
- Uncategorized
- VirtualBox
- Virtualization
- web development
- wine
- WMaker
- Wordpress Tips
- X Window System
- XFCE
-
Articles
- August 2020
- August 2019
- May 2019
- July 2017
- February 2017
- January 2017
- November 2016
- October 2016
- September 2016
- August 2016
- July 2016
- June 2016
- April 2016
- March 2016
- December 2015
- November 2015
- September 2015
- June 2015
- May 2015
- April 2015
- March 2015
- February 2015
- January 2015
- December 2014
- October 2014
- February 2014
- January 2014
- November 2013
- October 2013
- June 2013
- April 2013
- March 2013
- February 2013
- January 2013
- December 2012
- October 2012
- August 2012
- July 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- September 2011
- August 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
-
Meta
Cloud
audio bash boot compile C programming cups drupal emacs etc Fedora git grep how to httpd init kernel libc linux linux partition localtime login make mount mp3 mysql networking oracle package managers password phpMyAdmin programming rpm shell sql vbox version control system virtual box vm web server wordpress www xargs xfce xwin yum
[…] 参考:Makefile variables ($@, $< …),GNU make manual […]
It’s easy to debug a makefile in the target sections, just add a echo somewhere within your target section :
some-target:
@echo Value of VAR1=$VAR1
But sometimes you really need to check some value before your targets. What can you do? You can’t use echo in the definitions section…
This will do the trick! 😉
$(error VAR1 = $(VAR1).)
It will do the job of printing the value of the variable from within your makefile’s definitions section… Of course it WILL also break the build… but I am assuming that if you’re at the stage of debugging environment variables in your makefiles then this is probably not be your major concern at this very moment… 🙂
And even better yet – use $(warning …) instead of $(error …).
This method is described in detail in O’Reilly’s book “Managing Projects with GNU Make” and the chapter “Debugging Makefiles” is free and available on O’Reilly’s site as a PDF download:
http://www.oreilly.com/openbook/make3/book/index.csp
… and as HTML page:
https://www.oreilly.com/library/view/managing-projects-with/0596006101/ch12.html