새로운 블로그 개발중...

소스코드가 프로그램이 되는과정 즉 빌드 과정

정리대기
2015.01.14 14:06





프로그래밍 언어는 여러 종류가 있습니다. 우리는 Visual Studio나 이클립스같은 IDE를 통해 누구나 쉽게 자신만의 코드를 실행시키고 프로그램을 만들수가 있습니다. 그러한것은 IDE가 소스코드를 알아서 build해주기 때문입니다.


build는 소스코드가 실행할수있는 파일이 되기 까지의 과정을 칭합니다. Compiler, preparser, preprocceser, linker 등이 이에 포함됩니다.




Compile Languages (C/C++....)


컴파일 언어는 기계어로 바로 번역되어 실행되기 때문에 가장 속도가 빠르고 보안에도 유리합니다. 하지만 조금만 소스코드를 수정해도 다시 컴파일을 해야 반영되기 때문에 개발 생산성이 떨어집니다. 




컴파일 언어 빌드 이미지컴파일 언어 빌드



 1.Preprocessor(전처리기)

 #define 같은 매크로나 지시자를 전처리가 소스코드로 바꾸어준다 

 c파일은 이과정에서 i파일이 됩니다. 


2 Parser(데이터 추출, 데이터 분석)

이 파서가 바로 문법검사기입니다(Syntax Analyzer) 문자열을 입력받아 문법이 맞는지 체크합니다. 


3 Translation

말그대로 번역기, 그러니까 문법검사 마친 C언어 소스를 어셈블리어로 바꾸어준다 

i 파일은 이과정에서 s파일이 된다( 윈도우는 asm이던데)


4 Assembler

어셈블러는 어셈블리어를 기계어나 RTL같은 기계어만큼 낮은 수준의 언어로 바꾸어준다. 

s 파일은  o파일이 됩니다 (o는 오브젝티브 파일로써 그냥 바이너리코드 가들어있는 파일이라 생각하면된다)


5 Linker

링커 이녀석은 작성된 코드가 사용하는 시스템콜(OS API)나 C/C++표준 라이브러리를 불러와 말그대로 연결시켜준다 

만약 main.c가 win32API인 CreateFile함수를 쓴다면 링커는 User32.DLL이나 kernel32.DLL을 링크 시킬것입니다.

드디어 main.exe 파일이 만들어집니다. 


6. Disk

완성된 실행파일을 하드디스크에 쓰기를 통해 exe파일이 생성됩니다.


7 OS Exe Loader

로더는 해당파일을 메모리(주기억장치)에 적재시키는 역할을 한다. 

리눅스를 다루다 보면 grub이란 부트로더가있는데 이는 리눅스커널을 해당 시스템의 메모리에 적재시키는 프로그램이다 



Byte code languages (JAVA, C#....)



바이트코드는 가상기계어 개념으로 생각하시면됩니다. JAVA도 알다시피 컴파일을 합니다. 하지만 컴파일의 결과물이 실행파일이 아닌 class라는 바이트 코드 파일이죠. 이를 JRE(Java Runtime Environment), CLI(common language infrastructure)라는 인터프리터가 한줄씩 실행하여 동작합니다. CLI는 윈도우의 닷넷 계열 실행환경입니다. 이를 통해 컴파일러 즉 바이트코드 생성기는 C++ 컴파일러와 같지만 실행하는 JVM, CLI등의 인터프리터를 OS나 플랫폼 별로 만들어 Java라는 언어가 플랫폼 독립적으로 실행되는것입니다.


보통 자바는 C++보다 엄청 느리다. 라고하는데 이는 단정짓기 어려운 사실입니다. JRE 즉 바이트코드를 실행하는 JVM 은 바이트코드를 인터프리터 형식으로 실행하는데 이떄 C++ 처럼 기계어로 번역되어 실행합니다 또한 JVM(Java Virtual Machine)은 GC(Garbage Collector)를 튜닝할수 있기 때문에 어떤때는 C++보다 빠를수가 있습니다. 


하지만 분명한 사실은 자바같은 바이트 코드언어는 직접적인 하드웨어 제어가 불가능합니다. 소스 코드가 직접적으로 하드웨어에 반영되는게 아니기 때문이죠. 그래서 포인터나 Win32 API 같은 수준의 System call을 사용할수 없는 것입니다. 그러한 이유로 보안 관련 프로그램이나 극도의 optimization이 요구되는 프로그램에 C/C++등이 사용되는 것입니다.


결론은 자바가 확실한건 C++보다 개발생산성이 뛰어나고 직접전인 하드웨어 제어는 불가능하다 라는 점입니다.





자바의 빌드과정 이미지자바의 빌드과정




1 컴파일

Compiler에 의해서 java소스파일이 class파일로 바꾸어집니다.

이과정은 C++ 컴파일과정과 유사합니다 결과물이 어셈블리나 기계어가 아닌 바이트코드라는 점이 다른것입니다.


2.JRE안에서의 과정

먼저 바이트코드가 유효한지 검사합니다. 

CLASS 파일을 JRE가 메모리에 적재시킵니다. 


Just In-Time Compiler(JIT)

이 기술은 바이트 코드 형태의 언어 실행속도를 높이기 위한 기술로써 JRE에 포함된 JVM이 바이트코트를 실행할때 플랫폼별로 컴파일을 하는데 이과정에서 실제 실행코드가 기계어로 번역되어집니다. 


3. 실행

어떤 OS든 JAVA 코드가 같은 결과물을 내놓습니다.


즉 자바의 플랫폼 독립은  같은 소스코드와 실행결과를 말하는것이며

코드를 플랫폼 독립적으로 실행 시키기위해 OS별로 다른 방식의 JVM이나 JRE가 만들어집니다.  



Interpreter languages (Javascript, Python, Ruby...)



인터프리터 언어는 컴파일 언어와 다르게 한줄씩 바로 언어를 번역해서 실행됩니다. C++은 소스 파일이 전체 컴파일되는 반면 인터프리터는 한줄씩 컴파일되어 실행됩니다. 그렇기 때문에 번역하는 과정에서 메모리가 훨씬 적게 소모되기 때문에 효율적입니다


구글 크롬은 크로미늄이라는 오픈소스 프로젝트의 결과물입니다. 이 크로미늄은 오픈소스 이기 때문에 누구나 다운받아 빌드할수있습니다. 

과연 시간이 얼마나 걸릴까요? 검색해본결과 적어도 1시간이상 걸린다고 합니다. 이는 크로미늄은 C/C++로 작성되어 있기 때문인데요. 컴파일 과정에 필요한 메모리와 시간이 인터프리터에 비해 엄청나게 높고 오래걸립니다.

 

만약 파이썬으로 작성되어있다면 2시간은 커녕 길어야 5분일것입니다. 이것이 컴파일과 인터프리터의 차이입니다. 




인터프리터 언어의 실행과정 이미지인터프리터 언어의 실행과정



인터프리터는 즉시 실행될수있다는 장점때문에 실시간 분석이나 대화형으로 프로그래밍이 가능합니다. 여러분이 아시는 파이썬은 데이터마이닝, 빅데이터, 등의 연구 분야의 5위권 안에 드는 언어입니다. 반면 C++은 20위권 정도일것입니다.




Rerference