Compile a simple C program
The typical example of C language isHello WorldThe following is an example of code:
#include <stdio.h> int main(void) { printf("Hello, world!\n"); return 0; }
Assume that the code is saved as the file 'hello. C '. To useGccCompile the file and run the following command:
$ Gcc-g-wall hello. C-O hello
This command compiles the code in the file 'hello. c' into a machine code and stores it in the executable file 'Hello. The file name of the machine code is-OOption. This option is usually used as the last parameter in the command line. If omitted, the default output file is 'a. out '.
NotesIf the file with the same name as the executable file already exists in the current directory, it will be overwritten.
Option-WallEnable almost all common warnings of the compiler --We strongly recommend that you always use this option. The compiler has many other warning options,
-WallIs the most common. By default, GCC does not generate any warning information. When writing C or C ++ programs, the compiler warning is very helpful for detecting program problems.
NOTE: If it is useful to standard libraries that are not called by GCC by default, use the-LM parameter.
In this example, the compiler uses-WallNo warning is generated because the sample program is completely legal.
The "-G" option indicates that debugging information is included in the generated target file. The debugging information can help analyze the source of the error after the program is aborted to generate a core due to an exception, contains a lot of useful information such as the file name and row number that produce the error.
To run the program, enter the executable file path as follows:
$./Hello, world!
This loads the executable file into the memory and causes the CPU to start executing its contained commands. Path./Indicates the current directory, so./HelloLoad and execute the executable file 'hello' in the current directory '.
Capture Error
As mentioned above, the compiler warning is a very important helper when programming in C or C ++. To illustrate this, the following example contains a subtle error: an integer is incorrectly specified with a floating point Controller '% F '.
#include <stdio.h> int main (void) { printf ("Two plus two is %f\n", 4); return 0; }
The error is not obvious at a glance, but it can be captured by the compiler, as long as the warning option is enabled-Wall.
Compile the above program 'bad. c' and get the following message:
$ Gcc-wall-o bad. C main. c: In the 'main' function: Main. c: 5: Warning: The format '% F' requires the type 'double', but the type of real parameter 2 is 'int'
This indicates that the format string in row 'bad. c' is incorrectly used. GCC messages always have the following formatFile Name: row number: Message. The compiler treats errors differently from warnings. The former blocks compilation, while the latter indicates possible problems but does not block compilation.
In this example, for an integer, the correct format controller should be% D.
If not enabled-WallThe program appears to be compiled normally, but will produce incorrect results:
$ GCC bad. C-o bad $./Bad two plus two is 0.000000
Obviously, it is very dangerous to do not check the warning when developing a program. If a function is improperly used, the program may crash or produce incorrect results. Enable the compiler warning option-WallCaptures most common errors in C programming.
Compile multiple source files
A source program can be divided into several files. This facilitates editing and understanding, especially when the program is very large. This also makes it possible to compile each part independently.
In the following exampleHello WorldSplit the file into three files: 'Hello. C', 'Hello _ fn. C', and 'hello. H '. This is the main program 'hello. C ':
#include "hello.h" int main(void) { hello ("world"); return 0; }
In the 'hello. c' in the previous example, we call the library function.PrintfIn this example, we use a function defined in the 'hello _ fn. c' file.
HelloReplace it.
The main program contains the header file 'hello. H', which contains the FunctionHello. We do not need to include the system header file 'stdio. H' In the 'hello. c' file to declare the function.
PrintfBecause 'hello. c' is not called directlyPrintf.
The declaration in the file 'hello. H' specifies the function with only one row.Hello.
- Void Hello (const char
* Name );
FunctionHelloIn the 'hello _ fn. c' file:
#include <stdio.h> #include "hello.h" void hello (const char * name) { printf ("Hello, %s!\n", name);}
Statement# Include "file. H"And# Include <file. h>Different: before searching for the system header file directory, the former will first search for the file 'file. H' in the current directory, while the latter will only search for the system header file without viewing the current directory.
To useGccCompile the source file and run the following command:
$ Gcc-wall hello. c hello_fn.c-O newhello
In this example, we use-OSpecifies a different name for the executable file.Newhello. Note that the header file 'hello. H' is not specified in the command line. The
# Include "Hello. H"The indicator enables the compiler to automatically include it to a proper position.
To run this program, enter the path name of the executable file:
$./Newhello Hello, world!
Each part of the source program is compiled into a single executable file, which produces the same result as the previous example.
Simple makefile
For ease of familiarizationMakeThis section provides a simple usage example. With its own advantages, make can be found in all UNIX systems. For more information about GNU make, see
GNU makeManual.
Make fromMakefile(The default value is the file named 'makefile' in the current directory. Makefile specifies a seriesTarget(Such as executable files) andDependency(Such as object files and source files). The format is as follows:
Target: Dependent commands
For each target, make checks its corresponding dependent file modification time to determine whether the target needs to be re-created using the corresponding command. Note: In makefileCommandThe row must start with a single
TabCharacters are indented, not spaces.
GNU make contains many default rules (referImplicitRules) to simplify makefile construction. For example, they specify'. O'File can be compiled'. C'File, the executable file can be obtained'. O. Implicit rules are calledMake variableSuch
CC(C language compiler) andCflags(C program compilation options); In the MAKEFILE file, they use an exclusive
Variable = ValueIs set. PairC ++The equivalent variable isCxxAndCxxflagsAnd variableCppflagsIt is the compilation preprocessing option.
Now we will write a simple MAKEFILE file for the previous project:
Cc = GCC cflags =-wall Hello: Hello. O hello_fn.o clean: Rm-F hello. O hello_fn.o
This file can be read as follows: Use the C language compilerGcc, And the compilation option '-wall', which generates the target executable file from the object files 'hello. o' and 'Hello _ fn. o'.
Hello(The 'hello. o' and 'Hello _ fn. o' files are generated by 'hello. c' and 'Hello _ fn. c' by implicit rules respectively ). TargetCleanNo dependency file. It simply removes all compiled files.RmCommand Option '-f' (force) to suppress the error message generated when the file does not exist.
In addition, if the CPP file containing the main function is a. cpp, it is best to write the executable file name as a in makefile.
To use this makefile, enterMake. When make is called without parameters, the first target in the makefile is created to generate the executable file 'hello ':
$ Make gcc-wall-c-o hello. O hello. c gcc-wall-c-o hello_fn.o hello_fn.c GCC hello. O hello_fn.o-O hello $./Hello, world!
If a source file is modified, You need to generate an executable file again.MakeYou can. By checking the timestamp of the target and dependent files, the program make can identify which files have been modified and update their target files according to the corresponding rules:
$ Vim hello. C (open the editor and modify the file) $ make gcc-wall-c-o hello. O hello. c GCC hello. O hello_fn.o-O hello $. /Hello, world!
Finally, we remove the file generated by make and enter make clean:
$ Make clean Rm-F hello. O hello_fn.o
A professional MAKEFILE file usually contains additional targets such as make install and make check.
The examples involved in this article are simple enough that makefile is not required at all, but it is necessary to use make for any larger program.
Link External library
A library is a collection of pre-compiled object files that can be linked to a program. The static library is suffixed with '.'.Archive file)Storage.
The standard system library can be found in the directory/Usr/libAnd/Lib. For example, in Unix-like systems, the C-language mathematical library is generally stored as a file
/Usr/lib/libm.. The prototype Declaration of the function in this library is in the header file./Usr/include/Math. h. The C standard library is stored
/Usr/lib/libc.It contains functions specified by the ANSI/iso c standard, such as 'printf '. For every C program, libc. A is linked by default.
The following is a mathematical library called.Libm.MediumSinFunction example: create a fileCalc. c:
#include <math.h> #include <stdio.h> int main (void) { double x = 2.0; double y = sin (x); printf ("The value of sin(2.0) is %f\n", y); return 0; }
An attempt to generate an executable file from this file will result in a link phase error:
$ Gcc-wall Calc. c-o calc/tmp/ccbr6ojm. o: In function 'main':/tmp/ccbr6ojm. O (. text + 0x19): Undefined reference to 'sin'
FunctionSin, Which is not defined in this program or in the default library 'libc. A'. The Compiler does not link 'libm. A' unless specified '.
To enable the compilerSinLink to the main program 'calc. C'. we need to provide the Math Library 'libm. '. One easy-to-think but troublesome way is to explicitly specify it in the command line:
$ Gcc-wall Calc. c/usr/lib/libm. A-O calc
The function library 'libm. A' contains the target files of all mathematical functions, suchSin,Cos,Exp,LogAndSQRT. The linker searches all files to find
Sin.
OnceSinThe target file is found, and the main program can be linked. A complete executable file can be generated as follows:
$./Calc the value of sin (2.0) is 0.909297
The executable file contains the machine code of the main program and the function library 'lib.a '.SinThe corresponding machine code.
To avoid specifying a long path in the command line, the compiler provides a quick option '-l' for the linked function library '. For example, the following command
$ Gcc-wall Calc. C-lm-O calc
It is equivalent to the command '/ usr/lib/libm. A' for the specified full path of the library above.
Generally-LNameMake the linker try to link the library file in the system library directoryLibName.A. A large program usually uses a lot
-LTo specify the Math Library, graphics library, and network library to be linked.
Compile C ++ and FORTRAN
GCC is the acronym of the GNU Compiler Collection. The GNU Compiler set contains the front ends of C, C ++, objective-C, Fortran, Java, and Ada and libraries corresponding to these languages (libstdc ++, libgcj ,......).
Previously we only talked about C language. How can we compile other languages with GCC? This section describes how to compile C ++ and FORTRAN.
First, we try to compile a simple C ++ classic program.Hello World:
#include <iostream> int main(int argc,char *argv[]) { std::cout << "hello, world" << std::endl; return 0; }
Save the file as 'hello. cpp 'and compile it with GCC. The result is as follows:
$ Gcc-wall hello. CPP-O hello/tmp/cch6ouy9. o: In function '_ static_initialization_and_destruction_0 (INT, INT)': Hello. CPP :(. text + 0x23): Undefined reference to 'std: ios_base: init: Init () '/tmp/cch6ouy9. o: In function' _ tcf_0 ': Hello. CPP :(. text + 0x6c): Undefined reference to 'std: ios_base: init ::~ Init ()'
/Tmp/cch6ouy9. o: In function 'main': Hello. CPP :(. text + 0x8e): Undefined reference to 'std: cout' hello. CPP :(. text + 0x93): Undefined reference to 'std: basic_ostream <char, STD: char_traits <char> & STD: Operator <STD :: char_traits <char> (STD: basic_ostream <char,
STD: char_traits <char >&, char const *) '/tmp/cch6ouy9. O :(. eh_frame + 0x11): Undefined reference to '_ gxx_personality_v0' collect2: LD returned 1 exit status
Error !! There are still many errors, which are hard to understand. What should I do? Before explaining this, try the following command:
$ Gcc-wall hello. cpp-O hello-lstdc ++
After the-lstdc ++ option is added, the compilation is passed without any warning. Run the program. The result is as follows:
$./Hello, world
In the previous section, we can know that the-lstdc ++ option is used to notify the linker to link the static library libstdc ++.. It can be seen from the literal that libstdc ++. A is the standard library of C ++. As a result, we can easily understand the above problems-compiling the C ++ program requires linking the C ++ function library libstdc ++. a.
When compiling C, we do not need to specify the C function library. Why should C ++ be specified? This is because in the early days, GCC was the gnu c language compiler (gnu c compiler). With the addition of C ++, Fortran, and other languages, the meaning of GCC is changed to the GNU Compiler Collection ). C is the native language of GCC, so no additional options are required during compilation.
Fortunately, GCC contains a front-end compiler for C ++, Fortran, and other languages. As a result, the above example can be compiled directly using the following command:
$ G ++-wall hello. cpp-O hello
Gcc C ++ front-end is g ++, while FORTRAN is a bit complex: Before the gcc-4.0 version, Fortran front-end is G77, the Fortran frontend corresponding to the version after the gcc-4.0 is changed to gfortran. Below we will first write a simple Fortran sample program:
C Fortran sample program
Program helloworld write (*, 10)
10 format ('hello, World ')
End
Program helloworld
Save the file 'hello. F' and compile and run the file with the GCC Fortran frontend.
$ Gfortran-wall hello. F-O hello $./Hello, world
We already know that when we use GCC to compile C ++ directly, we need to link the C ++ standard library. How should we write the command when compiling Fortran with GCC?
$ Gcc-wall hello. F-o helloworld-lgfortran-lgfortranbegin
Note:: The above command is equivalent to the gfortran frontend (G77 is slightly different ). The library file libgfortranbegin. A (called through the command line option-lgfortranbegin) contains the start and exit code required to run and terminate a FORTRAN program. The library file libgfortran. A contains the required runtime functions such as the input and output of the bottom layer of FORTRAN.
For G77, the following two commands are equivalent (note that G77 corresponds to a version earlier than GCC 4.0 ):
$ G77-wall hello. F-O hello $ gcc-3.4-wall hello. F-O hello-lfrtbegin-lg2c
The two library files in the command line contain the start and exit codes of FORTRAN and the underlying running functions of FORTRAN.