C

include폴더와 lib폴더와 컴파일과 링킹

MDanderson 2024. 7. 25. 17:19

include폴더와 lib폴더

 

Visual Studio와 같은 개발 환경에서 include 폴더와 lib 폴더는 프로젝트의 빌드 과정에서 중요한 역할을 합니다. 각각의 폴더는 다음과 같은 목적을 가집니다:

1. include 폴더
include 폴더는 주로 헤더 파일(.h 또는 .hpp)을 저장하는 데 사용됩니다. 헤더 파일들은 함수, 클래스, 템플릿, 전역 변수, 매크로 등의 선언을 포함하고 있습니다. 소스 코드 파일(.cpp 등)에서 이 헤더 파일들을 포함(#include)함으로써, 해당 소스 파일은 헤더 파일에 선언된 기능을 사용할 수 있게 됩니다. include 폴더를 사용하는 주된 이유는 코드의 재사용성을 높이고, 모듈성을 향상시키며, 관리를 용이하게 하기 위함입니다.

2. lib 폴더
lib 폴더는 라이브러리 파일들을 저장하는 데 사용됩니다. 이 폴더에는 주로 정적 라이브러리(.lib)와 동적 링크 라이브러리(.dll)의 링크 파일이 포함됩니다. 정적 라이브러리는 프로그램이 컴파일될 때 전체 코드가 최종 실행 파일에 포함되며, 동적 라이브러리는 프로그램 실행 중에 필요한 부분만 메모리로 불러와 사용합니다. lib 폴더에 있는 라이브러리들을 프로젝트에 링크함으로써, 개발자는 그 라이브러리가 제공하는 함수, 객체 등을 사용할 수 있습니다.

프로젝트 설정
Visual Studio에서 이러한 폴더들을 올바르게 설정하는 것은 매우 중요합니다. include 폴더는 프로젝트의 "Include Directories" 설정에, lib 폴더는 "Library Directories" 설정에 추가해야 합니다. 이렇게 설정하면, 컴파일러와 링커가 이 경로들을 참조하여 필요한 헤더 파일과 라이브러리 파일을 찾을 수 있습니다.

 

컴파일과 링킹

 

lib 폴더에 있는 라이브러리 파일들이 프로젝트에 링크되는 것은 컴파일 단계가 아니라 링킹 단계에서 일어납니다. 이해를 돕기 위해 컴파일과 링킹의 차이와 각 단계에서 일어나는 일을 간략히 설명하겠습니다:

컴파일 단계
컴파일러는 소스 코드 파일(예: .cpp 파일)을 입력으로 받아 각 파일을 독립적으로 기계어 코드로 변환합니다. 이 때 생성된 출력 파일을 오브젝트 파일(예: .obj)이라고 합니다. 컴파일 단계에서는 주로 소스 코드 내의 구문을 분석하고, 오류 검사를 하며, 중간 코드를 생성하는 작업이 이루어집니다. 이 단계에서는 include 폴더의 헤더 파일들이 중요하게 사용됩니다. 헤더 파일에서 선언된 클래스, 함수, 변수 등을 소스 코드에서 참조하여 컴파일합니다.

링킹 단계
모든 소스 파일이 컴파일되어 오브젝트 파일이 생성된 후, 링커(linker)가 이 오브젝트 파일들과 필요한 라이브러리 파일들을 함께 결합하여 최종 실행 가능한 파일(예: .exe 파일)을 생성합니다. 이 과정에서 lib 폴더의 라이브러리 파일들이 사용됩니다. 정적 라이브러리(.lib)는 이 단계에서 코드 전체가 최종 실행 파일에 직접 포함되며, 동적 라이브러리(.dll)의 경우 실행 파일이 해당 라이브러리를 참조하도록 설정만 해두고, 실제 로딩은 프로그램 실행 시에 이루어집니다.

따라서, lib 폴더의 라이브러리 파일들은 링킹 단계에서 중요한 역할을 하며, 이를 통해 프로젝트에 필요한 외부 기능과 코드를 효과적으로 통합할 수 있습니다.

 

정적 라이브러리는 컴파일 단계에서는 직접적으로 포함되지 않습니다. 

정적 라이브러리의 코드는 링킹 단계에서 최종 실행 파일에 포함되는 것이 맞습니다. 여기서 컴파일 단계와 링킹 단계의 구분이 중요합니다:

컴파일 단계
컴파일 단계에서는 소스 코드(.cpp 등)를 기계어 코드로 변환하는 오브젝트 파일(.obj 등)을 생성합니다.
이 단계에서는 헤더 파일(.h, .hpp)만 참조하여 소스 코드 내의 선언된 심볼(함수, 변수 등)에 대한 정보를 확인하고 오브젝트 파일을 만듭니다.


링킹 단계
링킹 단계에서는 컴파일 단계를 거친 오브젝트 파일들과 함께 정적 라이브러리 파일(.lib 등)이 포함됩니다.
링커는 이 오브젝트 파일들과 정적 라이브러리의 코드를 모아서 하나의 실행 파일(.exe 등)을 생성합니다. 이 때 정적 라이브러리의 전체 코드가 최종 실행 파일 안으로 복사됩니다.
즉, 정적 라이브러리는 프로그램의 실행 파일을 만드는 링킹 단계에서 포함되어, 실행 파일 내에 코드가 완전히 통합됩니다. 그렇기 때문에 최종 실행 파일은 해당 라이브러리 없이도 독립적으로 실행이 가능합니다. 이 과정은 프로그램 실행 시에 별도의 라이브러리 로딩이 필요 없게 만들어, 성능상의 이점을 제공하곤 합니다.

 

헤더 파일(.h, .hpp)과 라이브러리 파일(.lib, .dll)

 

헤더 파일(.h, .hpp)과 라이브러리 파일(.lib, .dll)은 서로 다른 목적과 방식으로 사용되며, 각각의 역할이 프로그램 개발과 실행 과정에서 중요한 차이점을 가집니다. 이 두 종류의 파일은 코드의 구성과 배포 방식에서 다음과 같이 차이가 있습니다:

헤더 파일 (Header Files)
목적: 헤더 파일은 주로 함수, 클래스, 템플릿, 전역 변수, 매크로 등의 선언을 포함합니다. 이 파일들은 코드의 인터페이스를 정의하며, 실제 구현은 소스 파일(.cpp)에 있습니다.


사용 방법: 개발자는 소스 파일에서 필요한 헤더 파일을 #include 지시어를 통해 포함시킵니다. 이를 통해 컴파일러가 해당 헤더 파일에 선언된 요소들을 소스 코드에서 찾을 수 있도록 해 줍니다.


효과: 헤더 파일을 통해 코드의 모듈성과 재사용성을 높일 수 있으며, 프로젝트의 다른 부분이나 다른 프로젝트에서도 동일한 코드를 쉽게 사용할 수 있게 합니다.

 


라이브러리 파일 (Library Files)
목적: 라이브러리 파일은 컴파일된 코드(정적 라이브러리의 경우) 또는 실행 가능 코드(동적 라이브러리의 경우)를 포함하며, 실제 기능의 구현을 담고 있습니다.


정적 라이브러리(.lib): 이 파일은 링킹 단계에서 프로그램의 실행 파일에 직접 통합됩니다. 실행 파일은 별도의 라이브러리 로딩 없이 모든 기능을 포함하게 됩니다.


동적 라이브러리(.dll): 실행 시간에 필요한 코드가 메모리로 로드됩니다. 프로그램은 이 라이브러리 파일을 실행 중에 필요할 때 참조하여 사용합니다.


사용 방법: 개발자는 라이브러리 파일을 프로젝트 설정에서 링커에 명시하여 링크하고, 필요한 경우 헤더 파일을 통해 라이브러리의 인터페이스에 접근합니다.


효과: 코드의 실제 실행 가능한 부분이 라이브러리 형태로 제공되어, 프로젝트의 크기를 줄이고 관리를 편리하게 합니다. 또한, 동적 라이브러리의 경우 라이브러리 업데이트가 용이하며, 시스템 자원을 효율적으로 사용할 수 있습니다.


결론
헤더 파일은 "선언"을 제공하며, 라이브러리 파일은 "구현"을 제공합니다. 헤더 파일은 개발 과정에서 코드의 구조와 계약을 정의하는 반면, 라이브러리 파일은 실제 로직과 기능의 실행 코드를 포함합니다. 두 파일은 함께 사용되어 소프트웨어 개발의 효율성을 극대화하며, 코드의 재사용과 유지 관리를 쉽게 만듭니다.