⦁ Build 란?
컴퓨터는 근본적으로는 0과 1밖에 모른다. 우리가 작성하는 코드들은 거의 대부분 고급언어를 사용하기 때문에 결국에는 컴퓨터(CPU)가 이해할 수 있도록 번역을 해주어야한다. (C, Java, C++ 등 어셈블리를 제외한 대부분 언어가 고급언어다.)
컴퓨터가 이해하는 언어를 기계어라고 하는데, 우리가 만든 소스 코드가 컴퓨터 입장에서는 해외판 책이 되는 것이고, 이 책을 기계어(machine code)로 번역하여 컴퓨터에서 이해할 수 있는, 즉 실행 가능한 파일로 만드는 과정을 빌드(Build) 라고 한다.
⦁ Build Process
1. Compile Type
이렇게 한 번에 번역하는 언어들을 보통 Compile Language 라고 하는데, 대표적으로 C, C++, Go 언어가 있다. 이러한 언어들의 빌드 과정은 대개 아래와 같다.
[preprocessing (전처리)]
전처리 과정은 전처리기(preprocessor) 에 의해 소스코드에 포함 된 매크로나 지시자 같은 것을 포함시켜준다. 프로그래밍 언어로 보자면 C언어나 C++ 에서 # 으로 시작하는 구문들(#include, #define 등)이 있다.
[compilation (컴파일)]
컴파일 하는 프로그램을 컴파일러(compiler)라고 한다. C나 C++를 다뤄봤다면 gcc, g++, Visual C++ 같은 단어를 들어보거나 봤을텐데 이런 것들이 바로 컴파일러다.
컴파일러가 컴파일 하면 바로 기계어(Machine Code)로 번역 될 것 같지만 아니다. 흔히 중간언어 또는 저수준 언어로 번역된다. 보통은 어셈블리어(Assembly Language)로 번역된다.
과거에는 0과 1로만 작업을 했어야 하다보니 여간 불편하기 짝이 없었다. 예로들어 'A'라는 문자를 표현하려면 1000001. 이렇다 보니 이런 것들을 부호화(Symbolic) 한 것이다. 단순히 부호화만 했기 때문에 기계어(Machine Code)와 1대1 매칭이 된다. 그렇다 하더라도 우리가 사용하는 Java, C 같은 고급언어처럼 사람이 읽기 쉬운 언어가 아닌 난해한 언어인지라 저수준 언어(low-level language)에 속하게 되는거다.
저수준 언어답게 장점도 있다. 바로 내부가 어떻게 작동하는지, 즉 하드웨어를 직접적으로 조작하거나 특수 프로세서 명령어에 접근 등을 확인하거나 작업을 할 수가 있다는 것이다.
[assemble (어셈블)]
어셈블리어를 기계어로 번역해주는 프로그램을 어셈블러(Assembler)라고 한다. 이렇게 CPU가 이해할 수 있는 언어로 번역된 파일을 보통 Object File 이라고도 하는데, 직역하면 '객체 파일'이라고 하지만, 대부분은 객체라 하지 않고 '목적 파일'이라고 한다.
[linkig (링크/링킹)]
컴파일(어셈블 포함) 과정을 통해 각 파일들이 기계어로 번역되었다면 이제 하나로 연결해주어야 한다. 책을 번역할 때도 각 낱장별로 번역된 종이들을 하나로 모아 묶어야 책이듯, 각각의 Object File 은 기계가 이해할 수 있는 번역본일 뿐 실행을 할 수 있는 파일이 아니다. 즉, Object File 들과 필요한 라이브러리들을 연결 시켜주고 최종적으로 하나의 'executable file (실행가능한 파일)'로 만들어준다. 우리가 흔히 어떤 프로그램을 사용할 때 .exe 라는 확장자를 갖는 파일을 실행시킨다. 이 exe가 바로 executablue 의 줄임말이다.
컴파일 언어의 장점
- 빌드가 완료된 실행가능한 파일은 실행 속도가 빠르다다.
- 매번 번역할 필요 없이 실행 파일만 실행하면 되기 때문에 전체적인 시간면에서 효율적이다.
컴파일 언어의 단점
- 프로그램을 수정해야 할 경우 처음부터 빌드과정을 다시 거쳐야하기 때문에 특히나 대규모 프로그램에서는 생산성이 떨어진다.
- 플랫폼에 매우 의존적이다.
플랫폼에 의존적이라는 말은 가장 쉽게 이해하자면 윈도우 실행파일을 맥OS 에서 실행하지 못하는 상황을 생각하면 된다.
크게 두 가지 원인이 있는데, 먼저 어셈블리어의 경우 CPU 명령어 세트에 1대1로 매칭된다고 했다. 즉, CPU에 의존적이라는 것인데 CPU 명령 체계가 거의 비슷하긴 하나 완전히 같지는 않다. 그리고 다음으로는 CPU가 이해할 수 있게 번역하여 최종 실행파일로 만들기 위해 우리는 링크라는 작업을 해주었는데 이 과정에서 OS 마다 서로 다른 라이브러리가 있어 링커는 해당 OS에서 요구하는 라이브러리를 연결하게 된다.
이러한 이유 때문에 우리가 프로그램을 내려받을 때 윈도우용, 맥용, 64비트, 32비트 등 이렇게 각 버전에 맞는 프로그램이 존재하는 이유다. 한 예로 C언어의 경우 자료형 타입이 각 운영체제마다 크기가 다르다.
2. Interpreted Type
소스코드를 통번역 하는 것이 아닌 한 명령 단위로 해석하면서 즉시실행하는 방법이다. 좀 더 쉽게 생각하면 통역사를 생각하면 된다.
위 그림에서 컴파일 언어와 인터프리트 언어의 가장 큰 차이점은 바로 목적파일(Object File)을 생성하지 않고 바로(direct) 실행된다는 것이 가장 크다.
보통 이러한 인터프리터 언어에 가장 대표적인 언어는 자바스크립트(JavaScript), 파이썬(Python)과 루비(Ruby)로 알려져 있다.
쉽게 말하면 소스코드의 한 명령 세트마다 기계어(Machine Code)로 번역하면서 바로바로 실행해주는 방식을 인터프리트라 하고 이렇게 번역해주는 프로그램(또는 환경)을 Interpreter(인터프리터)라고 한다. 즉, 각 운영체제에 맞는 해당 언어의 인터프리터만 설치한다면 어느 운영체제에서든 해당 언어를 사용하더라도 동일한 결과를 얻을 수 있다는 것이다. 한마디로 플랫폼에 독립적이라는 것이다. 또한 이렇게 컴파일 과정 없이 인터프리터를 통해 바로 결과를 볼 수 있기 때문에 프로그램 수정에 매우 유리하다는 장점이 있다.
인터프리트 언어의 장점
- 컴파일 과정 없이 바로 실행하기 때문에 수정, 디버깅에 유리하다. (개발 속도 향상)
- 각 플랫폼에 지원하는 인터프리터만 있다면 실행 가능하기 때문에 플랫폼에 독립적이다.
인터프리트 언어의 단점
- 빌드 되어있는 컴파일 언어 프로그램보다 실행 시간이 느리다.
- 코드를 열면 다 보이기 때문에 보안에 좋지는 않다.
반대로 컴파일 언어에 비해 매 번 부분씩 번역해야하기 때문에 실행 속도는 느리다는 단점이 있지만 이 마저도 요즘 하드웨어의 스펙이 워낙 높아져 일반 사람들에게는 컴파일 언어와 인터프리터 언어의 실행 차이를 체감하기 힘들 정도라 오히려 개발 속도가 빠른 인터프리트 방식을 혼합하여 적용을 하려는 경향이 근래 많아졌다.
3. Hybrid Type
컴파일 방식과 인터프리트 방식을 혼합한 방법이다. 컴파일언어의 단점은 실행 가능한 파일이 플랫폼에 의존적이라는 것이지만 실행 속도가 빠르다. 반대로 인터프리터 언어의 단점은 실행속도는 느리지만, 플랫폼에 독립적이라 어느 플랫폼이든 번역기(인터프리터)만 있으면 실행 가능했다.
이 둘의 단점을 상호 보완하여 만들어 진 것이 바로 하이브리드 방식이다. 흔히 '바이트 코드 언어(Byte Code Language)' 라고 하고 가장 대표적인 언어로는 Java(자바)가 있다.
고급 언어로 작성된 소스코드를 바이트 코드(bytecode)로 변환한다. 바이트 코드란 일종의 중간 언어라고 생각하면 다. 그리고 VM(Virtual Machine : 가상머신) 이라는 프로그램에 의해 바이트코드를 기계어로 바꿔준다. 이 때 중요한 것은 바로 VM이라는 프로그램이다.
쉽게 생각하면 프로그램을 VM 이라는 가상머신에서 실행한다고 보시면 된다. 즉, 각 플랫폼에 맞는 VM들이 만들어져 있다면 우리는 같은 소스코드를 어느 플랫폼에서든지 동일한 결과를 얻어낼 수 있다는 것이다.
예전에 마인크래프트가 한참 유행일 때 마인크래프트를 실행하기 위해서는 Java 를 설치해야 했었는데 그 설치한 Java 프로그램에 바로 가상머신이 포함되어 있기 때문에 java로 코딩된 소스코드를 실행하기 위해 Java를 설치하라고 했던 것이다. JRE(Java Runtime Enviroment)
먼저 바이트코드(Byte Code)는 가상머신(Virtual Machine)이 이해할 수 있는 중간언어(intermediate language)라고 보면된다. 예로들어 Java를 컴파일하면 .class 파일이 생성될거다. 또는 C#의 CIL(common intermediate language). 바이트코드는 기계어는 아니지만 어셈블리어처럼 '기계에 조금 더 가까운 언어'로 되어있다.
다만 컴파일언어의 목적파일과 차이가 있다면 컴파일 언어에서는 하드웨어에 의해 처리되는 기계어로 되어있었다면, 바이트 코드 파일의 경우 하드웨어가 직접 처리하는 것이 아닌 소프트웨어(가상 머신)에 의해 처리된다는 것이다. 역으로 생각하자면 바이트코드는 해당 가상머신 전용 기계어라고 보면 된다.
VM 은 가상머신(Virtual Machine)의 줄임말인데, 쉽게 생각해서 가상 컴퓨터라고 보시면 된다. 하나의 컴퓨터 환경을 구현한거라고 보면된다. 바이트 코드는 이 가상머신이 이해할 수 있는 코드로 되어있고 그 가상머신 안에는 인터프리터 같은 해석기가 있어 이들이 바이트코드를 해석하여 각 OS에 맞게 명령어를 해석하고 작동하는 하나의 프로그램이라고 보면 된다.
쉽게 자바로 예로 들자면, 자바 소스코드를 컴파일 하면 .class 파일이 나온다. 이 파일만 있으면 JVM이 설치된 어느 컴퓨터에서든 실행 할 수 있을 뿐만 아니라 거의 동일한 결과를 내보일 수 있다.
가장 대표적인 VM은 Java Virtual Machine 인 JVM 이 있다. 또한 C#의 경우는 .NET의 CLR 이 있다. 이들의 장점은 VM(가상머신)이 해당 운영체제에 맞게 지원만 해준다면 플랫폼에 독립적으로 실행할 수 있다는 장점이 있다. 인터프리터랑 같은 원리인 것이다. (물론 VM이 인터프리트만 하는 것이 아니라 최근에는 컴파일 방식과 혼용하여 구현되어 있다. 대표적으로 JIT(Just-in-Time) 이 있다.)
즉, VM을 통해 '플랫폼에 독립적'인 장점을 갖고왔고, 초기 컴파일 단계를 통해 바이트코드로 기계어에 더 가까운 언어로 번역을 한 번 해놓았기 때문에 속도도 기존 인터프리터 언어에 비해 더 빠르다는 장점 또한 갖고오게 되었다.
하이브리드 언어의 장점
- 각 플랫폼에 지원하는 가상머신 있다면 실행 가능하기 때문에 플랫폼에 독립적이다.
하이브리드 언어의 단점
- 컴파일 언어처럼 하드웨어를 직접 제어하는 작업은 불가능하다.
'CS > OS & 하드웨어' 카테고리의 다른 글
세그멘테이션(Segmentation)이란? 세그멘테이션 vs 페이징 (0) | 2023.10.23 |
---|---|
아스키코드(ASCII Code) - 컴퓨터의 문자 처리 원리 (0) | 2023.10.08 |
아스키코드, 유니코드, UTF-8의 차이 (0) | 2023.09.10 |
메모리 (RAM) 구조 (0) | 2023.08.28 |
Virtual Memory - 가상 메모리 ( 필요한 이유 ) (0) | 2023.08.24 |