Project Makefile (10): make embedded function and make command display
[Copyright statement: reprinted. Please retain the Source: blog.csdn.net/gentleliu. Mail: shallnew at 163 dot com]
In this section, let's talk about the make functions. In the previous sections, we have talked about several functions: wildcard, patsubst, notdir, shell, etc. The call format of a common function is as follows:
$ (Funcname arguments)
Or
$ (Funcname arguments)
Among them, funcname is the name of the function to be called, which should be the embedded function of make; arguments is the function parameter, and the parameter and function name are separated by spaces. If there are multiple parameters, separate parameters with commas. A function call starts with "$" and uses parentheses or curly braces to enclose the function name and parameters. Generally, parentheses are used.
Below are some common functions:
1. Get the matching mode file name function-wildcard.
Usage: $ (wildcard PATTERN)
This function lists all file names in PATTERN format in the current directory. Returns the names of all matching PATTERN files in the current directory separated by spaces.
For example:
SRC_FILES = $(wildcard src/*.c)
Returns the list of all. c files in the src directory.
2. String replacement function-subst.
Usage: $ (subst FROM, TO, TEXT)
This function replaces the "FROM" character in the string "TEXT" with "TO", and returns the new string after replacement.
3. patsubst.
Usage: $ (patsubst PATTERN, REPLACEMENT, TEXT)
This function searches for words separated by spaces in "TEXT" and replaces the pattern "TATTERN" with "REPLACEMENT ". The PATTERN wildcard "%" can be used in the parameter "PATTERN" to represent several characters in a word. If the parameter "REPLACEMENT" also contains "%", "%" in "REPLACEMENT" will be the string represented by "%" in "TATTERN.
For example:
SRC_OBJ = $(patsubst %.c, %.o, $(SRC_FILES))
Replace all. c files in SRC_FILES with. o and return it to the SRC_OBJ variable.
This function functions like variable replacement, http://blog.csdn.net/shallnet/article/details/37529935
The variable replacement format is "$ (var: a = B)" or "$ {var: a = B}", which means, replace all "a" in the variable "var" with "B" string ending with ".
For example, we have a variable that represents all. c files. It is defined as "src_files = a. c B. c. c ".
To obtain the. o source files corresponding to these. c files. You can get the same result using the following two methods ::
$(objects:.c=.o)$(patsubst %.c,%.o,$( src_files))
4. filter function-filter.
Usage: $ (filter PATTERN ..., TEXT)
This function filters out all words that do not conform to the PATTERN in the string "TEXT" and retains all words that match the PATTERN. You can use multiple modes. The Mode generally needs to contain the pattern character "% ". When multiple modes exist, the mode expressions are separated by spaces. Returns all strings that conform to the PATTERN in the TEXT string separated by spaces.
5. The anti-filter function-filter-out.
Usage: $ (filter-out PATTERN..., TEXT)
This function is opposite to the "filter" function. Filter out all words that match the PATTERN in the string "TEXT" and retain all words that do not match the PATTERN. There can be multiple modes. When multiple modes exist, the mode expressions are separated by spaces.
6. Retrieve the directory function-dir.
Usage: $ (dir NAMES ...)
From the file name sequence "NAMES ..." Directory of each file name. The directory part of the file name is included in the file name before the last slash ("/") (including the slash. Returns the space-separated file name sequence "NAMES ..." Directory of each file. If there is no slash in the file name, the file is considered as a file under the current directory.
7. The file name function -- notdir.
Usage: $ (notdir NAMES ...)
From the file name sequence "NAMES ..." . The directory section refers to the section before the last slash ("/") (including the slash. Delete the contents in all file names. Only the non-directories are retained. File Name sequence "NAMES ..." The non-directory part of each file.
8. Use the suffix function-suffix.
Usage: $ (suffix NAMES ...)
Function from file name sequence "NAMES ..." To obtain the suffix of each file name. The suffix is the last part of the file name starting with "." (including the DoT number). If the file name does not contain a dot number, it is null. Returns the sequential "NAMES…" of file NAMES separated by spaces ..." The suffix sequence of each file in.
9. Use the prefix function-basename.
Usage: $ (basename NAMES ...)
From the file name sequence "NAMES ..." To obtain the prefix of each file name (the part after the DOT ). Prefix refers to the part before the last vertex in the file name. Returns the space-separated file name sequence "NAMES ..." Prefix sequence of each file in. If the file has no prefix, an empty string is returned.
Here we only talk about some common functions, and some other functions are not mentioned. We can refer to the makefile manual when using them.
Normally, make prints the currently executed command during compilation. When the compilation link option is very long, It outputs a lot of things on the screen, if I don't want to see a lot of things on the screen, we can add @ in front of the command so that the command won't be output to the screen. Let's try to modify it like this:
# makemake[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/ipc'make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/ipc'make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/tools'make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/tools'make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/main'make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/main'#
It is found that only the display of the Directory and the exit directory is displayed, so it is difficult to know the current compilation process. In fact, we can add a line similar to printing in the Rule command:
@ Echo "do something ......"
In this way, you can output what is currently being done without outputting the command being executed. Modify the rule as follows:
$(OBJDIR) :>---@echo " MKDIR $(notdir $@)...">---@mkdir -p $@ifneq ($(SRC_BIN),)$(BINDIR)/$(SRC_BIN) : $(SRC_OBJ)>---@echo " LINK $(notdir $@)...">---@$(CC) -o $@ $^ $(LDFLAGS)endififneq ($(SRC_LIB),)$(LIBDIR)/$(SRC_LIB) : $(SRC_OBJ)>---@echo " ARCHIVE $(notdir $@)...">---@$(AR) rcs $@ $^>---@echo " COPY $@ to $(SRC_BASE)/libs">---@cp $@ $(SRC_BASE)/libsendif$(SRC_OBJ) : $(OBJDIR)/%.o : %.c>---@echo " COMPILE $(notdir $<)...">---@$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
The compilation output is as follows:
# makemake[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/ipc' COMPILE ipc.c... ARCHIVE libipc.a... COPY ../../build/unix_dbg/lib/libipc.a to ../../libsmake[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/ipc'make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/tools' COMPILE base64.c... COMPILE md5.c... COMPILE tools.c... ARCHIVE libtools.a... COPY ../../build/unix_dbg/lib/libtools.a to ../../libsmake[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/tools'make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/main' COMPILE main.c... LINK target_bin...make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/main'#
There are still a lot of output for directory switching. we can disable it. This requires the make parameter. in make-C, -- no-print-is specified-
Directory parameters. Modify the Makefile rule in the top-level directory as follows:
$ (BUILDDIR):> --- @ echo "Create directory $ @... "> --- mkdir-p $ (BUILDDIR)/bin $ (BUILDDIR)/lib $ (MODULES):> --- @ $ (MAKE)-C $ (DIR) /$ @ MODULE =$ @ -- no-print-directorymain: tools ipcclean:> --- @ for subdir in $ (MODULES); \> --- do $ (MAKE) -C $ (DIR)/$ subdir MODULE =$ $ subdir $ @ -- no-print-directory; \> --- done compilation output: # make COMPILE ipc. c... ARCHIVE libipc. a... COPY .. /.. /build/unix_dbg/lib/libipc. a .. /.. /libs COMPILE base64.c... COMPILE md5.c... COMPILE tools. c... ARCHIVE libtools. a... COPY .. /.. /build/unix_dbg/lib/libtools. a .. /.. /libs COMPILE main. c... LINK target_bin... # make cleanrm-f .. /.. /build/unix_dbg/obj/ipc. o .. /.. /build/unix_dbg/lib/libipc. arm-f .. /.. /build/unix_dbg/obj/main. o .. /.. /build/unix_dbg/bin/target_binrm-f .. /.. /build/unix_dbg/obj/tools/base64.o .. /.. /build/unix_dbg/obj/tools/md5.o .. /.. /build/unix_dbg/obj/tools. o .. /.. /build/unix_dbg/lib/libtools. a #
It seems that the output is much more refreshing. In fact, we can also use make-s to completely disable command display.