Preface:
This article introduces the basic knowledge required for C Programming in Linux. In this article, we will learn the following:
Source program Compilation
Write makefile
Library Link
Program debugging
Header files and system help--------------------------------------------------------------------------------
1. source program Compilation
In Linux, If You Want To compile a C language source program, we need to use the GNU gcc compiler. The following example shows how to use the GCC compiler.
Suppose we have the following simple source code (hello. C ):
Int main (INT argc, char ** argv)
{
Printf ("Hello Linux/N ");
} To compile this program, we only need to execute it in the command line:
Gcc-O hello. c
The GCC compiler generates a hello executable file for us. Execute./hello to see the output result of the program. In the command line, GCC indicates that we use GCC. To compile our source program. The-O option indicates that the executable file name output by the compiler is "hello" and "hello. c" is our source program file.
The GCC compiler has many options. Generally, we only need to know a few of them.-O options are known, indicating that the output executable file name.-C option is required. We only require the compiler to output the target code, and do not need to output executable files.-G indicates that we require the compiler to provide information for future debugging of the program during compilation.
With these three options available, we can compile our own simple source program. If you want to know more options, you can view the GCC help documentation, there are many details about other options.
2. Write makefile
Suppose we have the following program, the source code is as follows: /* Main. C */
# Include "mytool1.h"
# Include "mytool2.h" Int main (INT argc, char ** argv)
{
Mytoolpattern print ("hello ");
Mytool2_print ("hello ");
} /* Mytool1.h */
# Ifndef _ mytool_1_h
# DEFINE _ mytool_1_h Void mytooltypesprint (char * print_str ); # Endif /* Mytool1.c */
# Include "mytool1.h"
Void mytooltypesprint (char * print_str)
{
Printf ("this is mytool1 print % s/n", print_str );
} /* Mytool2.h */
# Ifndef _ mytool_2_h
# DEFINE _ mytool_2_h Void mytool2_print (char * print_str ); # Endif
/* Mytool2.c */
# Include "mytool2.h"
Void mytool2_print (char * print_str)
{
Printf ("this is mytool2 print % s/n", print_str );
} Of course, because this program is very short, we can compile it like this.
Gcc-C main. c
Gcc-C mytool1.c
Gcc-C mytool2.c
Gcc-O main. O mytool1.o mytool2.o
In this way, we can also generate the main program, which is also troublesome from time to time. However, if one day we modify one of the files (for example, mytool1.c) So do we have to re-enter the above command? Maybe you will say that this is easy to solve. I can write a shell script so that she can help me to complete it. Yes, for this program, yes But when we want to make things more complex, if our program has hundreds of source programs, should the compiler recompile them one by one?
For this reason, the smart programmers come up with a good tool to do this. This is make. We only need to execute the following make to solve the above problem. Before making, we need to compile a very important file. -- makefile. For the above program, the possible MAKEFILE file is:
# This is the MAKEFILE file of the above program.
Main: Main. O mytool1.o mytool2.o
Gcc-O main. O mytool1.o mytool2.o
Main. O: Main. c mytool1.h mytool2.h
Gcc-C main. c
Mytool1.o: mytool1.c mytool1.h
Gcc-C mytool1.c
Mytool2.o: mytool2.c mytool2.h
Gcc-C mytool2.c With this MAKEFILE file, we only need to execute the make command when we modify the file in the source program, our compilers only compile the files related to the files we modified. She doesn't even want to handle other files.
Next we will learn how to compile makefile.
In makefile, # the start line is a comment line. The most important thing in makefile is to describe the dependency of the file. The general format is:
Target: Components
Tabrule The first line indicates dependency, and the second line indicates rules.
For example, the second line of the MAKEFILE file above
Main: Main. O mytool1.o mytool2.o
The dependent object (components) of Target main is dependent on Main. O mytool1.o mytool2.o. If the object is modified after the target is modified, it is necessary to execute the command specified by the rule line, as shown in the third line of makefile above. Line gcc-O main. O mytool1.o mytool2.o note that the tab in the Rule line indicates that there is a tab key
Makefile has three very useful variables: $ @, $ ^, and $ <, which indicate the following meanings:
$ @ -- Target file, $ ^ -- all dependent files, $ <-- the first dependent file.
If we use the above three variables, we can simplify our MAKEFILE file:
# This is the simplified makefile.
Main: Main. O mytool1.o mytool2.o
Gcc-o $ @ $ ^
Main. O: Main. c mytool1.h mytool2.h
Gcc-C $ <
Mytool1.o: mytool1.c mytool1.h
Gcc-C $ <
Mytool2.o: mytool2.c mytool2.h
Gcc-C $ < After simplification, our makefile is simpler, but sometimes people want to be simpler. Here we will learn the default rule of a makefile.
. C. O:
Gcc-C $ < This rule indicates that all. O files are dependent on the corresponding. c files. For example, if mytool. O depends on mytool. C, makefile can be changed:
# This is the simplified makefile.
Main: Main. O mytool1.o mytool2.o
Gcc-o $ @ $ ^
. C. O:
Gcc-C $ < Well, our makefile is similar. If you want to know more about makefile rules, you can view the relevant documents.
3. Library Link
Compile the following program. /* Temp. C */
# Include Int main (INT argc, char ** argv) { Double value; Printf ("value: % F/N", value ); } This program is quite simple, but the following error occurs when we compile it with GCC-O temp. C.
/Tmp/cc33kydu. O: In function 'main ':
/Tmp/cc33kydu. O (. Text + 0xe): Undefined reference to 'log'
Collect2: LD returned 1 exit status This error occurs because the compiler cannot find the specific implementation of log. Although we include the correct header file, we still need to connect to the determined library during compilation. in Linux, When using mathematical functions, we must connect to the mathematical library. Therefore, we need to add the-LM option. GCC-O temp. C-lm so that we can correctly compile the program. Maybe someone wants Q: Why didn't I connect to the library when I used the printf function? Yes. For the implementation of some common functions, the GCC compiler will automatically connect to some common libraries, so that we do not need Specify the path of the library. Sometimes we need to specify the path of the library when compiling the program. In this case, we need to use the-L option of the compiler to specify the path. For example, we have a library in/home. /Hoyt/mylib, so we need to add-L/home/Hoyt/mylib during compilation. For some standard libraries, we do not need to point out the paths as long as they are in Start with the default library path. the default library path of the system is/lib/usr/local/lib. Path.
Another problem is that sometimes we use a function, but we don't know the library name. What should we do at this time? Sorry, I don't know the answer to this question. I have only one silly question. Method. first, I went to the path of the standard library to check if there are any libraries related to my functions. Then I found the library file (libpthread) of the thread function. a ). when However, if you cannot find it, there is only one stupid method. For example, if you want to find the library where the sin function is located, you have to use nm-O/lib/*. So | grep sin> ~ /Sin command, and then see ~ The/sin file is found in it. In the sin file, I will find this line of libm- 2.1.2.so: rj9fa0 W sin so that I know sin in the libm-2.1.2.so library, I can use the-LM option (remove the previous Lib and later versions of the logo, M is left, so it is-lm). If you know how to find it, please let me know, I am very grateful. Thank you!
4. program debugging
The program we write is unlikely to succeed at one time. In our program, there will be many unexpected errors. At this time, we will debug our program.
The most common debugging software is GDB. If you want to debug the program on the GUI, you can select xxgdb now. Remember to add the-G option during compilation. You can see the Help File of GDB. since I have never used this software, I cannot tell how to use it. however, I do not like GDB. it is annoying to track a program. I usually use it in a program. Output the value of the intermediate variable to debug the program. of course, you can choose your own method, and there is no need to learn from others. now we have a lot of IDE environments with the debugger. you can select a few Try to find a favorite use. 5. header files and system help
Sometimes we only know the approximate form of a function, do not remember the exact expression, or do not remember the description of the function in the header file. At this time, we can seek help from the system.
For example, if we want to know the exact form of the fread function, we only need to execute the man fread system to output the detailed explanation of the function and the header file of the function. Description Note: if we want to write the description of this function, when we execute man write, the output result is not what we need, because what we want is to write the description of this function. Description of the write command. To get the description of the write function, we need to use man 2 Write. 2 to indicate that the write function we use is For unified calling functions, another commonly used function is 3, which indicates that the function is a C library function. Remember that at any time, man is our best assistant. --------------------------------------------------------------------------------
Well, this chapter tells us so much about it. With this knowledge, we can enter the exciting C program adventure in Linux.
A thousand miles away! Http://www.fanqiang.com)
Go to the [UNIX Forum] |