Qaupot Blog
Software Engineering, Trip

302. 헤더 파일 / Linking 과정

🕐 Tue, 04 Feb 2014 09:00:00 GMT 🕓 Fri, 20 Aug 2021 11:05:00 GMT

헤더 파일

#include <stdio.h>

int main(int argc,char** argv)
{
	printf("Hello World\n");
	return 0;
}

main 함수에서는 printf 라는 함수를 호출 했었습니다.
이 함수는 직접 작성한 함수는 아닌, 라이브러리로써 컴파일러 제조사에서 제공해줍니다.

이 함수의 정의는 stdio.h라는 헤더 파일내에 정의되어 있으며,
코드를 작성할때 적었던 #include <stdio.h> 전처리 구문에 의해 참조됩니다.

  • <> 는 프로젝트 및 환경변수에 설정된 경로로부터의 탐색이며,
  • "" 는 현재 소스코드가 위치한 디렉토리로부터의 탐색입니다.

불러오는 파일의 확장자는 주로 .h를 사용하며 헤더파일이라는 의미를 갖습니다.
C++의 헤더파일 정의에서는 .h를 붙이지 않도록 정의하고 있지만, 아직 많은 프로그래머들은 .h의 확장자를 사용하고 있습니다.

목적코드

위 이미지는 지난번에 작성했었던 Hello World 프로젝트의 폴더입니다.
Debug(혹은 release)라는 폴더 밑에, main.obj 라는 파일을 보실 수가 있습니다.

이 파일이 main.cpp 가 기계어(목적코드, object code)로 변환된 모습입니다.

  • 목적코드는 각각의 함수들을 각각 하나의 기계어 집단으로 번역해놓은 코드입니다.
  • 이 단계까지는 각각의 함수들을 번역하는 과정이기 때문에 다른 함수와의 호출관계는 고려되지 않습니다.
  • 컴파일러마다 다릅니다만, Visual Studio 의 C/C++ 컴파일러는 소스코드 파일 하나당 하나의 중간 object 파일을 생성합니다.
int func(int value);

위처럼 구현부가 없이 정의만이 존재하는 함수는, "이런 함수가 어딘가에 존재할 것이다"라는 사실을 컴파일러에게 알려줍니다.

  • 실제 구현부는 같은 소스코드(동일한 목적코드 파일) 내부에 있을수도 있고, 혹은 다른 목적코드 파일에 들어있을 수도 있습니다.
  • 일단 이 정보가 있다면 설령 함수 실체가 어디에도 존재하지 않더라도, 이 소스코드는 목적코드로 컴파일 할 수 있습니다.

링커는 이러한 목적코드들을 모아 최종적인, 하나의 실행파일로 만들어 냅니다.

  • 하나의 실행파일로 만들어 낸다는 것은 각 목적코드들을 적당한 위치에 배치하고, 그들의 호출관계를 확립한다는 의미를 가집니다.

main 함수에서 printf 함수를 사용할 수 있었습니다. 이는 stdio.h에 그 함수에 대한 정의가 포함되어 있기 때문입니다.
그리고 이 printf 함수에 대한 목적코드는 OS가 제공하는 목적코드 파일에 포함되어 있습니다.

  • "stdio.h" 파일은 표준 입출력에 대한 함수들의 정의를 담고 있고 있으며, 구현은 OS 에서 제공하는 object 파일에 기계어의 형태로 포함되어 있습니다.
  • main.c파일 에서는 stdio.h 파일을 참조하고 있으며, 해당 파일에 포함되어 있는 함수의 정의들이 포함되었다고도 할 수 있습니다.

링킹

목적코드들을 하나의 실행파일로 모으면 목적코드에 "위치"가 생깁니다.

  • 0번부터 10번까지 main 함수를 배치했다면, 11번부터 20번 혹은 다른 어떠한 위치에 printf 함수를 배치해야 합니다.
  • "위치"가 생기면서, 비로소 함수간의 호출관계를 확립할 수 있게 됩니다.
    • main 함수에서 printf 함수를 호출하려면 printf 가 어디에 위치해 있는지 알 필요가 있기 때문입니다.

링킹 과정에서 함수의 목적코드를 찾을 수 없다면 링킹 에러가 발생합니다.

이후 운영체제가 이 파일이 실행 가능한 파일임을 알 수 있도록, 몇 가지 추가 정보를 덧 붙여 파일에 기록한 뒤, 만들어낸 결과물을 기록합니다. 결과물은 일상적으로 말하는 실행파일입니다.

  • 실행파일에도 규격이 있습니다. Windows 에서는 PE 라는 파일 포맷을, Linux 에서는 ELF 를 사용합니다.
이 블로그는 개인 블로그입니다. 게시글은 오류를 포함하고 있을 수 있지만, 저자는 오류를 해결하기 위해 노력하고 있습니다.
게시글에 별도의 고지가 없는 경우, 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 라이선스를 따릅니다.

This blog is personal blog. published posts may contain some errors, but author doing efforts to clear errors.
If post have not notice of license, it under creative commons Attribution-NonCommercial-NoDerivatives 4.0.