1.2 GCC 컴파일러 사용법
이 책에서는 작성한 코드를 GCC 컴파일러를 통해 컴파일하고 테스트하는 부분이 많습니다. 이를 위해 GCC 컴파일러를 사용하는 방법을 소개할게요.
먼저 명령행에서 gcc 메뉴얼을 확인하세요.
$ man gcc
GCC(1) GNU
NAME
gcc - GNU project C and C++ compiler
SYNOPSIS
gcc [-c|-S|-E] [-std=standard]
[-g] [-pg] [-Olevel]
[-Wwarn...][-pendantic]
[-Idir...][-Ldir...]
[-Dmacro[=def]...][-Umacro]
[-foption...][-mmachine-option...]
[-o output] [@file] infile...
...
옵션을 사용하지 않고 gcc 명령을 내리면 컴파일후에 링킹 과정을 거쳐 a.out 결과물이 만들어집니다.
//ex_gcc1.c #include <stdio.h> int main() { printf("hello, linux\n"); return 0; } |
$gcc ex_gcc1.c
$./a.out
hello, linux
만약 원하는 출력 결과로 만들려면 -o [출력 결과]를 사용하세요.
$gcc -o ex_gcc1 ex_gcc1.c
$./ex_gcc1
hello, linux
-c 옵션을 사용하면 컴파일을 수행하고 확장자가 o인 목적 파일을 만들어 줍니다. 실행이 가능하려면 링킹 과정을 거쳐야 실행 파일이 만들어집니다.
//ex_gcc2.c int Add(int a,int b) { return a+b; } |
$ gcc -c ex_gcc2.c
$ ls
ex_gcc2.o ex_gcc2.c
목적 파일을 포함하여 컴파일 할 때는 단순히 목적 파일도 입력 파일 목록에 열거합니다.
#include <stdio.h> int main() { printf("result:%d\n",Add(3,4)); return 0; } |
$ gcc -o ex_gcc3 ex_gcc2.o ex_gcc3.c
$ ./ex_gcc3
result:7
소스 파일 여러 개를 입력 파일 목록에 열거하여 컴파일할 수도 있습니다.
$ gcc -o ex_demo ex_gcc2.c ex_gcc3.c
$ ./ex_demo
result:7
-D 옵션을 사용하면 매크로 상수를 옵션으로 정의할 수 있습니다. 단순히 -DTEST처럼 매크로 상수명을 정의하면 1로 정의하며 -DTEST=8처럼 매크로 상수 값도 지정할 수 있습니다.
//ex_gcc4.c #include <stdio.h> int main() { #ifdef TEST printf("%d\n",TEST); #else printf("Not defined\n"); #endif return 0; } |
$ gcc -o ex_gcc4 ex_gcc4.c
$ ./ex_gcc4
Not defined
$ gcc -o ex_gcc4 -DTEST ex_gcc4.c
$ ./ex_gcc4
1
$ gcc -o ex_gcc4 -DTEST=8 ex_gcc4.c
$ ./ex_gcc4
8
목적 파일을 라이브러리로 만들 때는 ar 명령어를 사용합니다. 이 때 만들려고 하는 라이브러리 이름의 시작을 lib로 시작하게 작성하세요.
$ gcc rscv libdemo.a ex_gcc2.o
그리고 이와 같이 작성한 라이브러리를 포함하여 컴파일할 때는 -l 옵션을 주고 라이브러리 파일을 표현하는데 파일명 앞의 lib부분과 뒤쪽 .a를 생략합니다. 그리고 라이브러리 파일이 있는 경로를 -L 옵션으로 표시하세요.
$ gcc -o test ex_gcc3.c -L./ -ldemo
$ ./test
result:7
공유 라이브러리로 컴파일 할 때는 -shared -fPIC -o 옵션을 사용합니다.
$ gcc -shared -fPIC -o libshare.so ex_gcc2.o
공유 라이브러리를 포함하여 컴파일하는 방법은 정적 라이브러리를 포함하여 컴파일하는 방법과 같습니다.
$ gcc -o test2 ex_gcc3.c -L./ -lshare
$ ./test2
./test2: error while loading shared libraries: libshare.so: cannot open shared object
file: No such file or directory
하지만 실행해보면 제대로 동작하지 않습니다. 공유 라이브러리를 사용하는 프로그램은 라이브러리 디렉토리에 참조하는 라이브러리 파일이 존재해야 동작합니다. 슈퍼 유저 권한으로 로긴 계정을 변경한 후에 libshare.so 파일을 /usr/lib 디렉토리로 옮겨주세요.
$ cp libshare.so /usr/lib/
$ ./test2
result:7
정적 라이브러리는 컴파일 결과물에 포함하지만 공유라이브러리는 결과물에 포함하지 않습니다. 공유 라이브러리는 프로그램 동작 시에 라이브러리를 사용할 수 있게 링크하여 사용하므로 /usr/lib 디렉토리에 배치해야 동작하는 것입니다. 만약 라이브러리의 규모가 크고 이를 참조하여 사용할 수 있는 프로그램의 종류가 많을 수 있다면 공유라이브러리로 만들 것을 고민해 보세요.
이 외에도 gcc 컴파일 옵션에는 경고를 출력 결과에 echo하지 않게 -w 옵션을 줄 수 있고 헤더 파일의 경로를 지정하는 -I 옵션과 gdb 유틸로 디버깅할 수 있게 -g 옵션 등을 사용할 수 있습니다.
보다 자세한 사항은 별도의 레퍼런스를 참고하세요. 그리고 이 책에서는 make 명령을 이용하여 효과적인 프로젝트 관리 기법을 다루지 않으므로 별도로 학습을 권합니다.
'프로그래밍 기술 > 리눅스(Unix) 시스템 프로그래밍' 카테고리의 다른 글
[리눅스/유닉스 시스템 프로그래밍] fnctl, sync, fsync (0) | 2016.04.05 |
---|---|
[리눅스/유닉스 시스템 프로그래밍] dup, dup2 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] 파일 테이블과 파일 디스크립터 테이블 (2) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] lseek (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] read, write (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] open, close (0) | 2016.04.05 |
[리눅스/유닉스] 파일 입출력 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] 파일 시스템 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] 리눅스 (0) | 2016.04.05 |
[리눅스/유닉스 시스템 프로그래밍] 들어가기에 앞서 (0) | 2016.04.05 |