C 컴파일 기초

마이클의 AI 연구소·2022년 3월 15일
0

모듈 빌드

개요

C언어의 기본적인 컴파일과 링크방법에 대해 알아보고 실습해봅시다.

컴파일과 링크

컴파일

  • 한 언어로 작성된 프로그램을 다른 언어로 변환하는 과정
  • 여기서는 C언어를 CPU가 이해할 수 있는 기계어로 변환하는 과정을 말함
  • .c ⇒ .o
    • gcc -c test.c

링크

  • 오브젝트 파일들을 연결하여 실행가능한 파일로 만드는 과정
  • 재배치 가능 오브젝트, 실행 오브젝트, 라이브러리
  • object 파일을 실행모듈로 변환
  • .o ⇒ executable module
    • gcc -o test test.o

빌드

  • 컴파일 + 링크

실습1

실행모듈과 라이브러리를 제작하여 컴파일 후, 링크하여 실행 결과를 출력한다.

파일작성

func.c

int add(int a, int b)
{
		return a + b;
}

int mul(int a, int b)
{
		return a * b;
}

test.c

#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc <=2) {
        printf("two parameters required!\n");
        return -1;
    }

    int a = atoi(argv[1]);
    int b = atoi(argv[2]);
    int c = add(a, b);

    printf("%d + %d = %d\n", a, b, c);

    return 0;
}

컴파일

# func.o 생성
gcc -c func.c

# main.o 생성
gcc -c test.c 

링크

# test 생성
gcc -o test.c func.o

실행

./test 1 2 
# 출력 : 1 + 2 = 3

라이브러리 링크

정적라이브러리 링크

# 정적 라이브러리 생성
ar crf libtest.a test.o

# 정적 라이브러리 링크
gcc -o main main.o -L. -ltest

# dynamic dependency 체크
ldd main

동적라이브러리 링크

# 동적 라이브러리 생성
gcc -shared -fPIC -o libtest.so test.o

# 동적 라이브러리 링크 (동적라이브러리가 우선)
gcc -o main main.o -L. -ltest

# dynamic dependency 체크
ldd main

makefile

프로젝트 구성이 방대할 경우, gcc를 이용하여 일일이 빌드하는 것은 효율적이지 않습니다. make 유틸을 활용하면 보다 효율적으로 빌드를 수행할 수 있습니다.

make 를 사용하기 위해서는 makefile 을 먼저 구성해야 합니다. 해당 파일을 구성하고 make 를 실행하면 자동으로 빌드가 되며 -f 파라미터를 이용하여 파일명을 지정할 수 있습니다.

makefile의 구성

makefile은 크게 목표(Target), 의존성(Dependency), 명령(Command)의 3 부분으로 이루어집니다.

target:         dependencyList
                commandList
요소설명
targetList명령이 수행되어 생성될 결과 파일 지정
dependencyListtarget(목표)을 수행하기 위해 필요한 의존 관계 설정
commandListtarget을 수행하기 위해 여기에 정의된 명령이 실행됨

Command(명령)의 경우 다양한 유틸리티를 사용할 수 있습니다. 예를 들어 gcc 외에도  clearcp 등의 대부분의 명령어를 사용할 수 있습니다. 명령의 앞 부분은 반드시 Tab을 이용해서 공백을 만들어주어야 합니다.

make 예제

다음과 같은 파일들이 존재한다고 가정해봅시다.

  • main.c
  • input.c
  • output.c

위의 파일들은 gcc를 이용했을 때 다음과 같이 빌드할 수 있습니다.

$ gcc -o snowdeerApp main.c input.c output.c

이 경우 make를 위한 makefile로 만들어보면 다음과 같습니다.

snowdeerApp :
    gcc -o snowdeerApp main.c input.c output.c

기본적으로 위와 같은 makefile을 이용하면 되지만, 향후 확장을 위해 다음과 같이 좀 더 유연하게 만들어 줄 수 있습니다.

main : main.o func1.o func2.o
    gcc -o main main.o func1.o func2.o

main.o : main.c
    gcc -c main.c

func1.o : func1.c
    gcc -c func1.c

func2.o : func2.c
    gcc -c func2.c

makefile의 매크로 사용

위에서 작성한 makefile에 ‘$(매크로)’ 같은 형식의 매크로 기능을 사용할 수 있습니다.

OBJECTS = main.o func1.o func2.o
SRC = main.c func1.c func2.c

CFLAGS = -g
TARGET = main

$(TARGET) : $(OBJECTS)
    $(CC) -o $(TARGET) $(OBJECTS)

clear :
    rm -f $(OBJECTS) $(TARGET) core

main.o : main.c
func1.o : func1.c
func2.o : func2.c
profile
늘 성장을 꿈꾸는 자들을 위한 블로그입니다.

0개의 댓글