makefile--pattern Rule (vii)

Source: Internet
Author: User

Original blog, reprint please indicate the source--Zhou Xuewei http://www.cnblogs.com/zxouxuewei/

In the previous section, the directory was created successfully, the target file is not produced to the corresponding directory, here we first to the target file with the corresponding directory, so that the corresponding target file will be generated directly to the corresponding directory. We first add the path to the library file target and the executable file target, as follows:

    LIB: $ (objdir) $ (libdir)/$ (src_lib)            Bin: $ (objdir) $ (BINDIR)/$ (src_bin)            $ (objdir):      >[email protected ] "   MKDIR $ (notdir [email protected]) ..."      >[email protected]-p [email protected]            ifneq ($ (src_bin),) c10/>$ (BINDIR)/$ (Src_bin): $ (src_obj)      >---$ (CC)-o [email protected] $^ $ (ldflags)      endif ifneq            ($ ( Src_lib)      $ (libdir)/$ (src_lib): $ (src_obj)      >---$ (AR) RCS [email protected] $^      >---cp [email Protected] $ (src_base)/libs      endif  

Then do make and look at the build directory tree when you are done:

    build/      └──unix_dbg          ├──bin          │   └──target_bin          ├──lib          │   ├──libipc.a          │   └── LIBTOOLS.A          └──obj              ├──ipc              ├──main              └──tools  

You can see that the target of the build is in the corresponding directory. We victory and modified the. o file. Each of our previous module makefile is roughly written like this:

    Src_base =..                                                                                                                                                                                      /..                                                                                          CFLAGS + =                                                                                                                                                         Cppflags + =-I.-i./inc-i$ (src_base)/include # SRC _obj = $ (Patsubst%.c,%.O, $ (wildcard *.c)) Src_files = $ (wildcard src/*                                                                                                                                                 . c) Src_obj = $ (SRC_FILES:.C=.O)                                                                                                 Src_lib = xx.a                                                                                   Include $ (src_base)/makefile.rule   

Where Src_obj is given here and then used in Makefile.rule, the. o file here will be generated in the same directory as the. c file, so we now need to add the. o file to the path, Since the obtained path is inside the makefile.rule, we can uniformly assign the variable src_obj in the Makefile.rule, roughly as follows:
Src_obj = $ (Patsubst%.c, $ (objdir)/%.O, $ (Notdir $ (src_files)))
Here is the function Patsubst, notdir, about the function will be mentioned later. The. o file will be generated in the appropriate directory after it is generated as a target.
Compile again at this time:

    # make      make[1]: Entering directory '/HOME/MYPROJECTS/EXAMPLE_MAKE/VERSION-2.9/SRC/IPC '      make[1]: * * * No rule to Make target '. /.. /BUILD/UNIX_DBG/OBJ/IPC/IPC.O ', needed by '. /.. /BUILD/UNIX_DBG/LIB/LIBIPC.A '.  Stop.      MAKE[1]: Leaving directory '/HOME/MYPROJECTS/EXAMPLE_MAKE/VERSION-2.9/SRC/IPC ' make      : * * * [IPC] Error 2      #  

An error was found and was not successful when generating the target file IPC.O, and the build directory tree did not generate. o files. Why does the build fail?
We did not give the rules for generating. O targets, which can be generated previously because make has the ability to automatically derive through implicit rules (as mentioned earlier, links past). Before we modify it, build. O is done by means of an implicit rule:

    %.O:%.c      #  commands to execute (built-in):      

Because all the. O targets conform to this rule, the generated. o file is automatically deduced. We are now in the. o The previous add path does not conform to the generated. O's implicit mode rule, so the file is not generated, resulting in a compilation error. What about that? There is no implicit schema rule, and we can write ourselves to match the pattern rule that generated the target.
A pattern rule is similar to a normal rule, except that in a pattern rule, the target file is a file with the pattern character "%", using the pattern to match the target file. The portion of the target file name that matches "%" is called the "stem". When using a pattern rule, the target file is matched to get "stem", relying on the "stem" to produce the corresponding dependent file, the dependent file must be present or can be created.
So, let's add a pattern rule as follows:

    $ (objdir)/%.O:%.C      >---$ (CC)-C $ (CFLAGS) $ (cppflags) $<-o [email protected]  

The schema rule in which the target file is $ (objdir)/%.O, then there is now a rule that conforms to the. o file that we need to build, compile it:

 # make make[1]: Entering directory '/home/myprojects/example_make/version- 2.9/SRC/IPC ' make[1]: * * * No rule to make target '. /.. /BUILD/UNIX_DBG/OBJ/IPC/IPC.O ', needed by '. /..  /BUILD/UNIX_DBG/LIB/LIBIPC.A '.      Stop.  MAKE[1]: Leaving directory '/HOME/MYPROJECTS/EXAMPLE_MAKE/VERSION-2.9/SRC/IPC ' make: * * [IPC] Error 2 # 

Finding or not, has the schema rule been added, and why hasn't the. o file been generated?

Let's talk first about static mode rules:
There can be multiple targets in a rule, and the commands defined by the rule are valid for all targets. A rule with multiple goals is equivalent to multiple rules. The commands for a rule differ in the execution of different targets, because the automation variable "[email protected]" may be used in the command of the rule. A multi-objective rule means that all targets have the same dependent file. Multiple targets are typically used in the following two scenarios: although in multi-objective rules, different commands can be used depending on the target (using the automation variable "[email protected]" on the command line). However, multi-objective rules do not automatically change dependent files according to the target file (as in the example above using the automation variable "[email protected]" To change the rules of the command). The need to achieve this is to use the static mode of make.
A static mode rule is a rule in which a rule has multiple targets, and a different target can automatically construct a dependent file based on the name of the target file. A static mode rule is more generic than a multi-objective rule, and it does not require multiple targets to have the same dependency. However, dependent files in a static mode rule must be similar rather than identical
Of The static mode rule syntax is as follows:

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

For example, here is a static mode rule:

    objects = foo.o BAR.O all            : $ (objects)            $ (objects):%.o:%.c      $ (CC)-C $ (CFLAGS) $<-o [email protected]  

This rule describes all the. o File dependent files for the corresponding. c file, for the target "FOO.O", take its stem "foo" instead of the corresponding dependency pattern "%.c" in the mode character "%" can be obtained after the target's dependent file "FOO.C". This is the dependency "foo.o:foo.c" of the target "foo.o", and the command line of the rule describes how to complete the build target "FOO.O" compiled by "FOO.C". The command line "$<" and "[email protected]" are automation variables, "$<" represents the first dependent file in the rule, "[email protected]" represents the target file in the rule. The above rule describes the following two specific 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  

(Note: the example and its related description excerpt from the Internet, the description is very good, the estimate is more detailed than I said)

What is the difference between the static-mode rule and the normal pattern rule (non-static mode rule)? Both are file dependencies in the rules that target patterns and dependency patterns are used to build targets, and the difference is the timing at which make uses them when executing.
Static mode rules can only be used during the reconstruction of those files that are explicitly stated in the rules. cannot be used in the reconstruction of any other file, and it is unique to each target specified. If a target exists in two rules, and both rules define a command, make executes with a prompt error.
A non-static mode rule can be used on any target that matches it, and when a target file conforms to multiple target patterns, make will use the pattern rule that matches the first target as the rule to rebuild it.

Do you have any thought that if we specify a pattern rule, then there is an implicit rule, then how do you choose which pattern rule to execute? The pattern rule explicitly specified in Makefile overrides the implied pattern rule. That is, if there is a pattern rule in the makefile that is appropriate for the target file, then make will no longer look for other implied rules for the target file, and use the rule that appears in makefile directly. When used, the explicit rule always takes precedence over the implied rule.

Let's go on to the previous question, after we have defined the schema rule or not generated the. o File, we now change it to a static rule and try it again, as follows:

    $ (Src_obj): $ (objdir)/%.O:%.C                                                                                                                                                                >---$ (CC)-C $ (CFLAGS) $ (cppflags) $<-o [email protected]  

After execution:

    # make      make[1]: Entering directory '/HOME/MYPROJECTS/EXAMPLE_MAKE/VERSION-2.9/SRC/IPC '      make[1]: * * * No rule to Make target ' ipc.c ', needed by '. /.. /BUILD/UNIX_DBG/OBJ/IPC/IPC.O '.  Stop.      MAKE[1]: Leaving directory '/HOME/MYPROJECTS/EXAMPLE_MAKE/VERSION-2.9/SRC/IPC ' make      : * * * [IPC] Error 2      #  

The discovery hint does not have a file ipc.c, which indicates that there is no build. o because there is no. c file, and I'm curious why not use non-static mode for hints? (still do not understand, research and research, know can give a hint ha ~ ~)
Lack of dependent files, why not *.c files, think about our. o file does not have a. c file in the same directory. In our project, the source code and binaries (. o files and executables) are arranged in different directories for differentiated management. In this case, we can use the Directory search dependent file feature provided by make. This function is described in the next section, which says enough and is a bit tired. Unfortunately, there is still no available makefile, which will be given in the next section.

makefile--pattern Rule (vii)

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.