[Erlang_question34]erlang.mk's source Reading 1-Getting Started makefile

Source: Internet
Author: User

Through the ERLANG.MK project, master the basic makefile grammar, you can customize the makefile.

1. Makefile Basic rules:
1. All the source files are not compiled, then compile and link the individual source files to generate the final executable program; 2. Each source code file that has been modified since the last time the make is executed will be recompiled at the time of this execution . 3. Header files have been modified since the last time the make was performed. All source files containing this header file will be recompiled at the time of this execution.
2. Basic format:
TARGET ...: Prerequisites ... COMMAND
...

2.1 target is usually the last file name to be generated or the intermediate procedure file name necessary for this purpose.

It can also be the name of an action performed by make, such as the target "clean": pseudo target (phony targets).

2.2 prerequisites (dependent conditions) The list of file names required to generate the rule target. Usually a target depends on one or more files.

2.3 Command (command line) arbitrary shell commands or programs that can be executed under the shell.

It restricts the actions required for make to execute this rule. You can have multiple command lines, one for each command line.

Note : Each command line must start with the [tab] character, and the[tab] character tells Make that this line is a command line, and the make program itself does not care how the command works, Updates to the target file require that you provide the correct command in the rule description.

What the "make" program does is execute the command defined by the rule when the target program needs to be updated.

recommendation : Single-objective, multi-dependent. That means try to do it. There is only one target file in a rule, there can be multiple dependent files. Try to avoid using multi-objective, single-dependency methods.

The most amazing thing is that all three elements can use variables, and the variables can be expanded using wildcard characters.

3. Actual combat (build ERLANG.MK Project)

Here's a look at the basic makefile work steps by erlang.mk the project's own build process:

# #makefileBUILD_CONFIG_FILE? = $ (CURDIR)/Build.configbuild_config= $ (Shellsed "s/\#.*//"$ (build_config_file)) ERLANG_MK=erlang.mkerlang_mk_version= $ (Shell git describe--tags--dirty). Phony:all Checkall:awk 'fnr==1 && nr!=1{print ""}1'$ (Patsubst%,%. mk,$ (build_config))|sed 's/^erlang_mk_version =. */erlang_mk_version = $ (erlang_mk_version)/'>$ (ERLANG_MK) ifeq ($ (p),) check:$ (make)-C TestElsecheck:$ (make)-C Test pkg-$ (p) endif

These are the erlang.mk files that are generated by Build.config to our project itself (note that this is not a build custom project, but just a build erlang.mk, and then use it to build our custom project), which includes variable assignments. References, special variables Pseudo Target, ultimate goal, conditional statement:

3.1 Variables

1  make reads the makefile file, the variables here include the definition of "=" and the use of the indicator "define".  2. Variables can be used to represent a list of file names, compile a list of options, run the program parameter lists, search the source file directory list, compile the output directory list and all we can think of things.  3. The variable name does not include ":", "#", "=4." Variable names are case-sensitive.  52. Assigning values to variables

3.1.1 Recursive expansion variables

Syntax: VAR = Value

sed " s/\#.*// " $ (build_config_file))

Using a variable definition of this style may cause make to fail in the process of infinite variable expansion due to the recursive definition of the variable. as follows:

CFLAGS = $ (CFLAGS) –O

If a function is used in a variable definition of this style, the function contained in the value of the variable is always executed where the variable is referenced (when the variable is expanded).

3.1.2 Direct Expansion variables

Syntax VAR: = Value
A reference to another quantity or function in a variable value is expanded when the variable is defined (replacing the variable)

x: = Foo y:= $ (x) Bar x:= later# is equivalent to: y:= foo Bar x:= Later

3.1.3? = operator

Build_config_file = $ (CURDIR)/build.config

This variable is assigned only if the variable is not previously assigned.

Just because the variable is simply a macro expansion, and all of the makefile are first calculated from the beginning and end of the update rule, one time from the ultimate goal (the first goal) to execute. So in erlang.mk it is necessary to write the core part in front of the compilation (because a large number of parameters related to compiling erl are defined in the core).

3.2 References to variables

$ (build_config)    #或 ${build_config}

3.3 Special variables
$ (CURDIR) This variable represents the working directory of make. When you enter a subdirectory with the "-C" option, the variable is re-assigned. In summary, if you do not have an explicit assignment to this variable in Makefile, it represents the working directory of make.
$ (make) is used to recursively expand makes to take a different parameter, such as do: =/bin/make in another directory is yes: =/bin/make-t
3.4 Pseudo-target
Syntax: target is not a real file name
Reasons to use. Phony:all check: Avoid having a file in the directory called All or check, forcing this to be a pseudo-target.
3.5 command Line
Multiple commands written on the same line in Makefile belong to a full shell command line, and a command written on a separate line is a separate shell command line.
If you want to run multiple commands in the same shell, you should connect each command with \. Make it a one-line command.
3.6. Conditional statements:

-C testelse-C test pkg-

3.7 Shell command:

#把BUILD_CONFIG_FILE里面的所有注释去掉.
Sed's/pattern/replace_string' FileNamesed's /\#.*//"
#表示在除了第一个文件croe/core.mk, the first line of the other files must be preceded by a blank line. 1 indicates a return value of 1
awk 'begin{print "Start"} pattern{commands} end{print "END"} fileawk 'fnr==1 && nr!=1{print ""}1'$ (Patsubst%,%. mk,$ (Build_config)) #展开后:awk 'fnr==1 && nr!=1{print ""}1'CORE/CORE.MK Index/*. Mk core/index.mk core/deps.mk plugins/protobuffs.mk core/erlc.mk core/docs.mk core/test.mk plugins/asciidoc.mk Plugins/bootstrap.mk plugins/c_src.mk plugins/ci.mk plugins/ct.mk plugins/dialyzer.mk plugins/edoc.mk plugins/ Elvis.mk plugins/erlydtl.mk plugins/escript.mk plugins/eunit.mk plugins/relx.mk plugins/shell.mk plugins/triq.mk Plugins/xref.mk plugins/cover.mk

AWK Special variables:
NR: Indicates the number of records, which corresponds to the current line number during execution
FNR: Represents the current line number of a single file, does not accumulate in multiple files, and NR accumulates.
3.8 make built-in functions

Patsubst%,%.mk,$ (build_config))

Add the first line of the Build_config. Mk End. Patsubst is an intrinsic function of makefile.

3.9 Ultimate Goal

By default, make executes the first rule in Makefile, and the first goal of this rule is called "final purpose" or "ultimate goal" (a goal that a makefile eventually needs to be updated or created).

4. ERLANG.MK Build custom Project

What is 4.1 core.mk responsible for doing?

  

Core.mk source code (point here), go over it together. Makefile knowledge used to define various variables: P

$ (makefile_list)
When a make program reads multiple makefile files, it includes the environment variable "makefiles" designation, command-line directives, default under current work, and the inclusion specified using the indicator "include". The file names that make read before parsing these files are automatically appended to the definition field of the variable "makefile_list"

$ (Lastword $ (makefile_list)))
$ (Lastword $ (makefile_list))
Take the last word: Built-in function
$ (Realpath $ (Lastword $ (makefile_list)))
Indicates that the path is converted to an absolute path (. .. ~ Translate to a specific path)
@
Current destination name (the file name of the target.)
$ (verbose_$ (V))

Variable names can also be used for stitching,

Remember: variables are just simple text expansion

V?=0
Verbose = $ (verbose_$ (V))
  
Conditional Judgment Statement
Ifeq ($ (PLATFORM),)
uname_s: = $ (Shell uname-s)
Export
Put a variable Export,tell make whether or not to export a particular variable to child processes.
Export PLATFORM
::

Double-colon rule when the dependent file is newer than the target. The rules will be executed. For a double-colon rule that has no dependencies but only the command line, when this target is referenced, the rule's commands are unconditionally executed. The general rule is that when the target file for the rule is present, the command of this rule will never be executed (the target file is always up to date).

When the same file is a target for multiple double-colon rules. These different rules will be handled independently, rather than merging all dependencies into a single target file like normal rules.

All:: Deps
$ (verbose) $ (make)--no-print-directory app
$ (verbose) $ (make)--no-print-directory rel

#这个也是终极目标! The first goal that appears in MK!
Define Name
Multi command
Endef

When using the indicator "define" to define a multiline variable or command package, the definition of the body (the contents between "define" and "Endef") is fully expanded to the place where the variable is referenced in Makefile (containing the comment lines in the definition body); All defined bodies are processed at the point where the variable is referenced, and the decision is whether it is a comment or a valid content.

Define Core_http_get
Wget--no-check-certificate-o $ (1) $ (2) | | RM $ (1)
Endef
#调用
$ (call core_http_get,$ (ELVIS), $ (elvis_url))


Built-in functions can be referenced here .  

There's an interesting feature in CORE.MK: It uses make erlang.mk to automatically update to the latest version of ERLANG.MK.

erlang-mk:    git clone https://github.com/ninenines/erlang.mk $ (erlang_mk_build_dir)    ifthencpfi    && $ (make) CP     $ (Erlang_mk_build_dir)/erlang.mk./erlang.mk    RM -RF $ (erlang_mk_build_dir)

Basically *.mk is this routine, then go to the point:

4.2 Erlang.mk How does a custom project build?

The previous section has talked about the entrance to makefile: The ultimate goal is all, and everything starts here.

 #core. MkAll:: Deps $ (verbose) $ (make)--no-print-Directory App $ (verbose) $ (make)--no-print-directory rel#deps. Mkifneq ($ (skip_deps),) Deps::ElseDeps:: $ (all_deps_dirs) ifneq ($ (IS_DEP),1) $ (verbose)RM-F $ (erlang_mk_tmp)/deps.logendif $ (verbose)mkdir-P $ (erlang_mk_tmp) $ (verbose) forDepinch$ (all_deps_dirs); Do         if grep-qs ^$ $DEP $$ $ (erlang_mk_tmp)/deps.log; Then             Echo-N; Else             Echo$ $DEP >> $ (erlang_mk_tmp)/Deps.log; if[-F $ $dep/gnumakefile] | | [-F $ $dep/makefile] | | [-F $ $dep/makefile]; Then$ (make)-C $ $DEP is_dep=1|| Exit $$?; Else                 Echo "Error:no Makefile to build dependency $ $DEP."; Exit1; fi         fi      Doneendif#erlc. Mkifeq ($ (wildcard Ebin/test) App:: App-BuildElseapp:: Clean app-Buildendif

You just have to look at these three Mk to get a clear idea of how they work, and no need to know the rules at all!

Feel here is still very interesting, ready to draw a diagram again next time! Let's get here first this week.

Week not happy ~

5. Reference documentation

5.1 erlang.mk GitHub Address

5.2 Makefile Chinese Manual

5.3 Makefile Quick Reference

6. Todo:

0.erlang.mk How do I organize dependencies?

1. How to compile in parallel (how to control the sequencing of parallelism)?

2. How to debug makefile?

3.makefile command-line tips?

4. How do I add a custom function to erlang.mk?

--------------------------------------------------------------------------------------------------------------- -----------------------------------

One Compile Success ~ ~

[Erlang_question34]erlang.mk's source Reading 1-Getting Started makefile

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.