Write Makefile with Me (v.)

Source: Internet
Author: User
Tags new set

vi. Multi-Objective

There can be more than one goal in the makefile rule, which supports multiple targets, and it is possible that many of our goals depend on a single file at the same time, and that the commands generated are broadly similar. So we can combine it. Of course, the execution commands for multiple target generation rules are the same, this may be a problem for us, but the good news is that we can use an Automation variable "$@" (about the automation variable, which will be described later), which represents a collection of all the goals in the current rule, which may be very abstract, Let's look at an example.

Bigoutput LITTLEOUTPUT:TEXT.G
Generate TEXT.G-$ (subst output,,$@) > $@

The above rules are equivalent to:

Bigoutput:text.g
Generate Text.g-big > Bigoutput
Littleoutput:text.g
Generate Text.g-little > Littleoutput

Where "$" in-$ (subst output,,$@) represents the execution of a makefile function named Subst, followed by a parameter. About functions, which are described later. This function here is the meaning of the intercept string, "$@" represents the set of targets, like an array, "$@" sequentially takes out the target and holds the command.


Seven, static mode

Static patterns can make it easier to define multiobjective rules, making our rules more resilient and flexible. Let's take a look at the syntax first:

<targets: <target-pattern>: <prereq-patterns ...>
<commands>
...


Targets defines a series of target files, which can have wildcard characters. is a collection of targets.

Target-parrtern is a model that indicates the targets, that is, the target set pattern.

Prereq-parrterns is the dependent pattern of the target, which is defined as a dependent target for the pattern of target-parrtern formation.

This description of these three things, may still not be clear, or give an example to illustrate it. If our <target-parrtern> is defined as "%.o", it means that our <target> collection will end with ". O", and if our <prereq-parrterns> is defined as "%.c", This means that the target set of <target-parrtern> is defined two times, and the method of calculation is to take the "%" in <target-parrtern> mode (that is, to remove the end of [. O]) and add the end of [. c] to it. A new set of forms.

Therefore, our "target mode" or "dependency mode" should have "%" this character, if you have a "%" file name, you can use the backslash "/" to escape, to indicate the true "%" character.

Look at an example:

objects = FOO.O BAR.O

All: $ (objects)

$ (objects):%.o:%.c
$ (CC)-C $ (cflags) $<-O $@


In the example above, indicates that our goal is obtained from the $object, and "%.O" indicates that all objects ending with ". O", that is, "foo.o bar.o", which is the pattern of the variable $object set, while the dependent mode "%.C" takes the "%" of the Mode "%.O", i.e. " Foo Bar, and add the suffix ". C" to it, so our reliance target is "foo.c bar.c". The "$<" and "$@" in the command are automation variables, and "$<" represents all the dependent target sets (that is, "foo.c bar.c"), and "$@" represents the target set (that is, "foo.o bar.o"). As a result, the above rules are expanded to be equivalent to the following rules:

Foo.o:foo.c
$ (CC)-C $ (cflags) Foo.c-o foo.o
Bar.o:bar.c
$ (CC)-C $ (cflags) Bar.c-o BAR.O

Just imagine, if our "%.O" has hundreds of, that we can use this very simple "static mode rules" to write a bunch of rules, it is too efficient. The use of "static mode rules" is flexible and, if used well, is a powerful feature. Look at one more example:


Files = FOO.ELC bar.o lose.o

$ (Filter%.o,$ (Files)):%.O:%.c
$ (CC)-C $ (cflags) $<-O $@
$ (Filter%.elc,$ (Files)):%.ELC:%.el
Emacs-f Batch-byte-compile $<


$ (Filter%.o,$ (files)) indicates that the Makefile filter function is invoked to filter the "$filter" set, as long as the contents of the mode is "%.O". Its content, I don't have to say more. This example shows a greater elasticity in the makefile.


viii. automatic generation dependencies

In makefile, our dependencies may need to include a series of header files, for example, if there is a "#include" defs.h "in our main.c", then our dependency should be:

MAIN.O:MAIN.C Defs.h

However, if it is a relatively large project, you must know which C files contain which headers, and you need to carefully modify the makefile when you add or delete headers, which is a very maintenance-free job. To avoid this heavy and error-prone thing, we can use a C + + compiled feature. Most C + + compilers support a "-m" option that automatically looks for header files contained in the source file and generates a dependency relationship. For example, if we execute the following command:

Cc-m MAIN.C

Its output is:

MAIN.O:MAIN.C Defs.h

Then the dependencies that are generated automatically by the compiler, so that you do not have to manually write a number of file dependencies, and the compiler automatically generated. To be reminded, if you are using the GNU C + + compiler, you have to use the "-mm" parameter, otherwise, the "-m" parameter will include some standard library header files.

The output of the Gcc-m main.c is:

MAIN.O:MAIN.C defs.h/usr/include/stdio.h/usr/include/features.h/
/usr/include/sys/cdefs.h/usr/include/gnu/stubs.h/
/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stddef.h/
/usr/include/bits/types.h/usr/include/bits/pthreadtypes.h/
/usr/include/bits/sched.h/usr/include/libio.h/
/usr/include/_g_config.h/usr/include/wchar.h/
/usr/include/bits/wchar.h/usr/include/gconv.h/
/usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stdarg.h/
/usr/include/bits/stdio_lim.h


The output of the gcc-mm main.c is:

MAIN.O:MAIN.C Defs.h

So how does this function of the compiler relate to our makefile? Because of this, our makefile will also be rebuilt according to these source files, so that makefile relies on the source file. This is not a realistic feature, but there are other ways we can do this in a roundabout way. The GNU organization recommends that the compiler put the automatically generated dependencies for each source file into a single file, generating a "NAME.D" makefile file for each "name.c" file, and a dependency for the [. c] File in the [. d] File.

So we can write dependencies on [. c] Files and [. d] Files and let make automatically update or become [. d] files and include them in our main makefile so that we can automate the generation of dependencies on each file.

Here, we give a pattern rule to produce the [. d] File:

%.D:%.c
@set-E; Rm-f $@; /
$ (CC)-M $ (cppflags) $< > $@. ; /
Sed ' s,/($*/)/.o[:]*,/1.o $@:, G ' < $@. > $@; /
Rm-f $@.


This rule means that all the [. d] Files depend on the [. c] File, "Rm-f $@" means to delete all the targets, that is, the [. d] File, the second line means "$<" for each dependent file, the [. c] File generates the dependent file, "$@" represents the Mode "%.D" Files, if there is a C file is name.c, then "%" is "name", "" means a random number, the second line generated by the file may be "name.d.12345", the third line using the SED command to make a replacement, for the use of SED command refer to the relevant documentation. The Forth line is to delete the temporary file.

All in all, this pattern is about adding dependencies to [. d] files in compiler-generated dependencies, that is, dependency:

MAIN.O:MAIN.C Defs.h

Turn into:

MAIN.O main.d:main.c Defs.h

So, our [. d] Files are also automatically updated and automatically generated, and of course, you can also add more than just dependencies in this [. d] file, including the generated commands, so that each [. d] file contains a dependency rule. Once we complete this work, we will then put these auto-generated rules into our main makefile. We can use the makefile "include" command to introduce other makefile files (previously mentioned), such as:

Sources = foo.c bar.c

Include $ (SOURCES:.C=.D)

"$ (SOURCES:.C=.D)" in the above statement. C=.d "means to make a substitution, replace the variable $ (sources) all the [. c] Strings with [. d], and I'll have a more detailed description of the" replacement ". Of course, you need to be aware of the order, because the include is loading the file on a per-time basis, and the target in the [. d] file that was first loaded becomes the default target.


Original: http://blog.csdn.net/haoel/article/details/2890

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.