리눅스 개발 환경 이해하기 (1)

2024. 11. 15. 15:30디바이스 드라이버

 

빌드 : 소스 코드를 실행할 수 있는 바이너리 파일로 만드는 과정

호스트 : 빌드가 실행되는 환경

타겟 : 빌드가 된 바이너리가 동작할 환경

 

우리가 모바일 앱을 만드는데 개개인의 노트북을 사용해서 앱을 만든다면 내가 만든 소스 코드가 기기에서 실행할 수 있는 형태로 변환하는 과정이 빌드이고, 호스트는 개발과 빌드 작업이 이루어지는 시스템인 내 노트북이되고, 타겟은 앱이 실제로 실행될 환경인 스마트폰이 된다.

 

우리가 만든 소스코드를 기기에서 실행할 수 있는 형태로 변환해주는 편리한 도구들의 모음이 있는데 그것이 바로 툴체인이다.

 

우리가 소스 코드를 만들면 그 자체로는 컴퓨터가 이해할 수 없다. 즉 바이너리 파일인 목적파일로 변경하는 과정이 필요한데 소스코드를 기계어로 번역하는 과정이 컴파일이다. 

컴파일로 생성된 목적 코드를 헤더파일,라이브러리,설명서 등을 포함한 SDK(Software Development Kit)를 모아 하나의 바이너리로 결합하면 실행파일이 나온다.

툴체인은 컴파일러, SDK,링커 등으로 이루어져있다.

 

간단한 실습으로 툴체인에 대해서 알아보겠다.

 

3개의 vim 파일을 만드는 데 각각의 이름은 distance.c , distance.h , main.c이다.

<distance.c>

 

<distance.h>

<main.c>

 

.h 파일은 C나 C++ 같은 언어에서 사용하는 헤더 파일이다. .h파일에는 함수의 선언만 포함되고, 함수의 실제 구현은 .c파일에서 이루어진다.

 

 

gcc -c *.c는 현재 디렉토리에 있는 .c파일들을 목적파일(.o)로 변환하는 명령어이다. 즉 컴파일을 나타낸다.

명령 후에는 목적파일인 distance.o와 main.o가 추가된 것을 알 수 있다.

 

그 다음 링킹을 나타내는 명령어인 ld *.o 명령을 사용하면 다음과 같은 에러메시지가 뜬다. 에러가 뜨는 이유는 Cannot find entry symbol_start는 C Runtime 목적파일이 없기 때문에 발생하고, Undefined reference to는 라이브러리를 지정해주지 않았기 때문에 나타나는 에러메시지이다. 우리가 c언어를 생각해보면 pow나 sqrt 함수를 사용하기 위해서는 <math.h>라는 헤더파일이 필요한데 위에는 stdio와 distance.h 헤더파일만 있기 때문에 컴퓨터입장에선 pow와 sqrt를 알아들을 수 없다. 또한 맨 밑에 printf라는 함수도 stdio 헤더파일이 있는데도 컴퓨터는 알아들을 수 없다는데 이를 통해 라이브러리도 링킹이 되어야 한다는 사실을 알 수 있다.

 

C Runtime 목적파일이 뭘까?

 

C Runtime 목적파일은 C언어의 main에 이르기까지의 초기화를 수행시켜주는 파일이다. 

 

이렇게 CRT 목적파일은 커맨드 라인 인수(argc,argv) 같은 정보를 준비한 후 main함수를 호출해준다. 그리고 main함수가 종료되면 반환 값을 전달받은 CRT 목적파일은 프로그램의 종료 루틴을 수행한다. (exit 명령어)

 

라이브러리는 어떻게 링킹해야할까?

 

리눅스에서 라이브러리의 기본 위치는 /usr/lib 또는 /usr/lib/x86_64-linux-gnu에 있다.

 

라이브러리의 사용법은 ld에서 사용시 lib 부분을 떼고 -l을 붙여서 사용한다. 예를 들어 C언어의 기본 함수가 들어가 있는 libc라이브리러리를 사용하려면 -lc, 수학 관련 라이브러리인 libm 을 사용하려면 -lm으로 사용해야한다.

 

 

위와 같은 방식으로 CRT 목적파일과 라이브러리를 한꺼번에 링킹해본다.

 

그러면 a.out이라는 파일이 생성된다. 그 이유는 출력 파일 이름을 지정하지 않았기 때문이다.

 

위와 같이 example이라는 이름을 지정해서 링킹을 해주고 example파일을 실행하면 잘 동작을 할까?

 

 

위와 같이 그런 파일이나 디렉터리가 없다고 뜬다. 이상하지 않은가? 분명 우리는 example이라는 파일을 만들었는데 왜 없다고 뜰까?

사실 example파일이 문제가 아니라 example에서 참조하는 파일이 존재하지 않기 때문에 저런 에러가 뜬다.

 

example이라는 파일이 의존하고 있는 라이브러리를 확인하기 위해 ldd명령어를 사용한다.

 

 

libm과libc는 존재하는데 맨 밑에 ld64.so.1이라는 파일이 없다. 그래서 위와 같은 에러메시지가 뜨면서 실행이 되지 않는다.