01_Script_makefile_summary
https://github.com/carloscn/blog/issues/167
01_Makefile_makefile_summary
A project has innumerable source files that are organized along various paths based on type, function, and module. The rules in the makefile state which files should be rebuilt, which files should be built later, and which files should be constructed first. The makefile prefers a shell with sophisticated functions.
1. grammer
1.1 basic
The
object
is the target to be compiled or an action.The
dependence
is a pre-item performing the object depended.One object allows having multiple dependencies.
The
command
is the specific command under the performing object.Each command occupies one line.
By default, the first object will be executed when no option is specified.
Examples: https://github.com/carloscn/clab/blob/master/macos/test_makefile/single/Makefile.hello
1.2 common options
By default, make command search GUNmakefile
makefiles
Makefile
in current directory using as the make input file, except for that use option-f
to specify a make file by filename.
-f
: specify a make file by file path-v
: show the version number-n
: perform the makefile, output commands record only, don't perform.-s
: perform the makefile, don't show commands record.-w
: show paths before and after execution.-C
: show paths where the makefile is located.
1.3 using a common include make
We can use a makefile as a public makefile liking as the function #include
in C language.
Note, the =
and :=
:
=
: the final value assignment, whatever the calling before the assigning value or behind the assigning value.:=
There is a example for describing the difference between =
and :=
:
The make a
output is 456 456 789
, and the make b
output is an error, becasue the object b cannot ensure the y value that referenced itself.
Now, we replaced the =
to :=
:
The make a
output is 456 123 789
, and the make b
is no longer an error, rather then 789 789
.
1.4 using the linux shell within makefile
https://github.com/carloscn/clab/blob/master/macos/test_makefile/Makefile.shll
1.5 using the nesting function of makefile
https://github.com/carloscn/clab/blob/master/macos/test_makefile/multi/src/Makefile
1.6 using condition define
https://github.com/carloscn/clab/blob/master/macos/test_makefile/Makefile
This is always combined gcc -D
with ifdef
. Sometimes, we want to use some variables of the makefile in a C source file, different variables different flows, such as using the debug, and setting the version number. Using the gcc -D
is equal to defining a macro by #define
.
And the test.c is :
So, we can utilize the ifdef
of makefile and -D
of gcc to do something.
1.7 using the foreach
In a makefile, the foreach can provide the loop function for us. We can make use of the foreach to create a directory or something.
https://github.com/carloscn/clab/blob/master/macos/test_makefile/Makefile
1.8 using the function
https://github.com/carloscn/clab/blob/master/macos/test_makefile/Makefile
2. make val
We need to set up a C build environment shown in the following picture, and you can find the original source code in https://github.com/carloscn/clab/tree/master/macos/test_makefile/single
The main.c file depends on add.c div.c mul.c sub.c, and the main.c is implement simple add or div functions by calling the sub-functions.
We written the makefile as follow:
It has a very basic makefile and appears quite silly. All the objects would be recompiled when we altered a single file. If the project is particularly large, compiling will take a lot of your time.
So we need to optimize the makefile and make it easier and more convenient.
When one of these files changed, the optimized makefile would re-compile the changed .c file.
2.1 using user env
Based on the simple makefile, we replaced *.o
files with OBJ
by user environment. The difference between the simple makefile and the new makefile is shown in the following figure:
2.2 using sys env
$*
: the object name that does not include the extension name.$+
: all the dependence files, seperated by space.$<
: the first condition in rules.$?
: the dependence files that the time later than object.$^
: all the dependence files are not repeated.$%
: if the object is an archive member, the variable indicates the member name of the object.
Based on the user env makefile, we replaced OBJ
and TARGET
with $^
and ^@
by the system environment.
The difference between these makefiles is shown in the following figure:
2.3 using build env
The build env can be shown by make -p
.
AS
: asCC
: gccCPP
: ccCXX
: g++ or c++RM
: rm -rf
Based on the system env makefile, we replaced gcc
to $(CC)
by build environment.
2.4 phony object
The phony object is that whether the file is changed or not, the object declared by phony must be performed.
If there is a hello file on your makefile path, and hello is still an object in your makefile. When the hello is not declared by phony:
If the hello is declared by .PHONY, the object will be performed by making command whether the file with the same name exists in the directory or not.
2.5 mode matching
%.*:%.c
: .o files depend on .c files corresponding.wildcard
:$(wildcard ./*.c)
obtain the all .c file in the current directory.patsubst
:$(patsubst %.c, %.o, $(wildcard *.c))
replace .c to .o corresponding.
using the wildcard
3. Using libraries
3.1 Using the dynamic library
When we generate a dynamic library on Linux:
-fPIC
: this is the position-independent code-shared
: this is specifying the type of dynamic library.
When we use a dynamic library on Linux:
-l
: this is specifying the dynamic library name-L
: this is specifying the path of the dynamic library.-I
: this is specifying the path of included files.
Now, we create files shown in the following figure:
cacu.c:
cacu.h:
Makefile:
3.2 Using the static library
As we compile a static library:
gcc -c hello.c -o hello.o
ar -r libhello.a hello.o
As we use a static library:
gcc -lhello -L./ main.c -o main.elf
Example:
Touch a mod.c
Touch a mod.h
The makefile is:
4. Make Note
There are some notes of the make tool.
4.1 ignore an error
Prevent the make command from stopping when the script runs into an error. If the make command captured the non-zero return value, the make script would halt and return this error. However, some errors in the process returned are meaningless. We can enable the function of make ignoring errors in your makefile script.
make -i
: ignore all errors during the making.phony object can be set to
.IGNORE
put the
-
before one command line.
4. Ref
最后更新于