Linux에서 gcc의 전체 이름은 "GNU Compiler Collection"이며, 이는 중국어로 "GNU Compiler Suite"를 의미합니다. GNU에서 개발한 프로그래밍 언어 컴파일러로 여러 언어를 컴파일할 수 있습니다. gcc 제품군에는 C, C++, Objective-C, Fortran, Java, Ada 및 Go 언어 프런트 엔드와 이러한 언어용 라이브러리가 포함되어 있습니다.
이 튜토리얼의 운영 환경: linux7.3 시스템, Dell G3 컴퓨터.
1. gcc란
GCC(GNU Compiler Collection, GNU 컴파일러 제품군)은 GNU에서 개발한 프로그래밍 언어 컴파일러입니다. GNU 컴파일러 제품군에는 C, C++, Objective-C, Fortran, Java, Ada 및 Go 언어 프런트 엔드는 물론 이러한 언어용 라이브러리(예: libstdc++, libgcj 등)가 포함되어 있습니다.
처음에는 gcc C 언어 컴파일러(GNU C Compiler)로 사용되었으며, 이제는 C 언어 외에도 C++, Java, Pascal 및 기타 언어도 지원합니다. gcc는 다양한 하드웨어 플랫폼을 지원합니다.
2. gcc의 특징
3 gcc 컴파일 과정
gcc 컴파일러는 크게 4가지 과정을 거칩니다:
전처리는 실제로 헤더 파일과 매크로를 확장합니다. 컴파일 단계에서 gcc는 다양한 언어의 컴파일러를 호출합니다. 예를 들어 c 언어는 컴파일러 ccl을 호출합니다. Gcc는 실제로 프로그램을 컴파일하는 과정에서 다양한 도구를 호출하는 도구 체인입니다. 어셈블리 단계에서 gcc는 어셈블리를 위해 어셈블러를 호출합니다. 연결 프로세스는 프로그램에 필요한 개체 파일을 실행 파일로 연결합니다. 어셈블러는 재배치 가능한 객체 파일을 생성합니다. 운영체제를 연구한 결과 소스 프로그램의 주소는 0부터 시작한다는 것을 알 수 있습니다. 이는 상대 주소이며 프로그램이 실제로 메모리에서 실행될 때의 주소는 확실히 0에서 시작하지 않습니다. 0. 0으로 시작하며, 소스 코드 작성 시 프로그램의 절대 주소를 알 수 없으므로 Relocation을 사용하면 소스 코드, 변수 등을 특정 메모리 주소로 찾을 수 있습니다.
다음은 이 과정을 표현하기 위한 그림입니다. 이 과정에서 파일의 접미사 변경에 주의하세요.
다음은 GCC 컴파일의 네 단계입니다.
4. 일반적인 gcc 옵션
일반적인 gcc 옵션을 살펴보겠습니다.
이제 소스 파일 hello.c가 있습니다. 여기에 몇 가지 gcc 사용 예가 있습니다.
使用gcc时可以加上-Wall选项。下面这个例子如果不加上-Wall选项,编译器不会报出任何错误或警告,但是程序的结果却不是预期的:
//bad.c #include<stdio.h> int main() { printf("the number is %f ",5); //程序输出了the number is 0.000000,结果错误 return 0; }
使用-Wall选项:
gcc -Wall bad.c -o bad
gcc将输出警告信息:
warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘int’ [-Wformat=] printf("the number is %f\n",5);
5、gcc编译多个文件
// hello.c #include<stdio.h> #include"hello.h" void printHello() { printf("hello world!\n"); }
//main.c #include<stdio.h> #include"hello.h" int main() { printHello(); return 0; }
//hello.h //仅包含函数声明 #ifndef _HELLO_ #define _HELLO_ void printHello(); #endif
编译这三个文件,可以一次编译:
gcc hello.c main.c -o main 生成可执行文件main
也可以独立编译:
gcc -Wall -c main.c -o main.o gcc -Wall -c hello.c -o hello.o gcc -Wall main.o hello.o -o main
独立编译的好处是,当其中某个模块发送改变时,只需要编译该模块就行,不必重新编译所有文件,这样可以节省编译时间。
6、使用外部库
在使用C语言和其他语言进行程序设计的时候,我们需要头文件来提供对常数的定义和对系统及库函数调用的声明。库文件是一些预先编译好的函数集合,那些函数都是按照可重用原则编写的。它们通常由一组互相关联的可重用原则编写的,它们通常由一组互相关联的用来完成某项常见工作的函数构成。使用库的优点在于:
库又可以分为静态库与动态库:
一般头文件或库文件的位置在:
7、生成静态库
为了生成.a文件,我们需要先生成.o文件。下面这行命令将我们的hello.o打包成静态库libhello.a:
ar rcs libhello.a hello.o
ar是gun归档工具,rcs表示replace and create,如果libhello之前存在,将创建新的libhello.a并将其替换。
然后就可以这样来使用静态库libhello.a
gcc -Wall main.c libhello.a -o main
还有另外一种使用方式:
gcc -Wall -L. main.c -o main -lhello 【lhello 是 libhello的缩写】
其中 -L.表示库文件的位置在当前目录下,由于libhello.a是我们自己生成的,并存放在当前录下下,所以需要加上-L.选项。默认库文件是在系统的目录下进行搜索。同样的,-I.选项用于头文件的搜索。
8、生成共享库
生成一个共享库,名称的规则是libxxx.so。将刚才hello.o生成libhello.so的命令为:
gcc -shared -fPIC hello.o -o libhello.so
生成了共享库之后,可以这样来使用共享库:
gcc -Wall main.o -o main -L. -lhello
该命令与使用静态库的命令相同,但是在共享库与静态库共存的情况下,优先使用共享库。
共享库有时候并不不在当前的目录下,为了让gcc能够找得到共享库,有下面几种方法:
拷贝.so文件到系统共享库路径下,一般指/usr/lib
在~/.bash_profile文件中,配置LD_LIBRARY_PATH变量
配置/etc/ld.so.conf,配置完成后调用ldconfig更新ld.so.cache
其中,shared选项表示生成共享库格式。fPIC表示产生位置无关码(position independent code),位置无关码表示它的运行、加载与内存位置无关,可以在任何内存地址进行加载。
9、库的搜索路径
库的搜索路径遵循几个搜索原则:从左到右搜索-I -l指定的目录,如果在这些目录中找不到,那么gcc会从由环境 变量指定的目录进行查找。头文件的环境变量是C_INCLUDE_PATH,库的环境变量是LIBRARY_PATH.如果还是找不到,那么会从系统指定指定的目录进行搜索。
相关推荐:《Linux视频教程》
위 내용은 리눅스에서 gcc란 무엇인가?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!