compile이란 source code를 computer가 이해할 수 있는 언어인 native code ( machine language.. 기계어 )로 번역해주는 것입니다.
compile의 단계는 보통 세 단계로 이루어집니다.
. lexical-phase - 어휘 분석을 합니다..
괄호가 빠졌다는지 semicolon이 빠졌다는 등의 error message가 다른 error보다 먼저 나오지요?
. syntactic-phase - 구문 분석을 합니다..
함수에 parameter가 있어야 하는데 안넣었다는 등의 error를 찾아주죠..
. semantic-phase - 의미를 분석합니다..
long a, *b;
a = b;
이건 syntax는 맞지만 의미상으론 틀렸죠.
long type에 long pointer type을 바로 대입할 순 없죠.. cast를 한다면 모를까..
이런 식으로 compile 과정이 진행되고 난 뒤엔 vc++ 이라면 .obj가 생깁니다.
님이 cpu와 os에 맞도록 code를 생성해서 xx.obj라고 만들어주는 것이죠.
compile과정은 이걸로 끝입니다.
하지만 이건 실행 file이 아니라서 실행할 수가 없습니다.
이제 exe나 dll같은 것을 만들기 위해선 build, 즉 link가 필요합니다.
그 전에 link의 필요성을 들어보죠..
#include < stdio.h >
void main()
{
printf( "%d\n", 1 );
}
라는 source를 만들었다고 치죠.
printf는 stdio.h에 선언되어 있으므로 compile은 잘됩니다.
그런데 printf의 몸체는 include된 stdio.h에도.. 지금 이 source file에도 없습니다.
막상 실행할 부분이 없다는 것이지요..
.lib라는 file이 바로 '이런 function같은 것들이 어느 file에 있다'라고 알려주는 역할을 합니다.
( 우리가 이미 알고 있다면 .lib 없이도 명시적으로 link할 수 있습니다. )
이런 정보를 이용해서 link를 하는 것입니다.
link를 하면서 같은 file( exe나 dll 등의 최종 목적 file )에 묶이게 되는 것을 static link library라고 하고 binary는 따로 있는 것을 dynamic link library라고 합니다.
dll이라고 많이 들어보셨죠?
거기엔 code 혹은 resource가 있어서 그걸 필요할 때 사용할 수 있다는 것도 알고 계시죠?
바로 그겁니다.
printf는 c runtime library 어디에나 다 있기 때문에 뭐 아무거나 link해도 다 될 겁니다.. ( libc, libcmt, msvcrt 에 있습니다 )
다른 예를 들어보죠..
#include < windows.h >
void main()
{
MessageBox( NULL, "text","caption", MB_OK );
}
라는 source를 compile하고 link하면, user32.dll에 있는 MessageBoxA를 쓰게 됩니다.
왜 MessageBox가 아니라 MessageBoxA냐구요.. 음..
위 source에서 MessageBox에 cursor를 놓고 F12를 눌러보세요..
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE
이런 식으로 MessageBoxA라고 정의되어 있는 걸 define해서 쓰고 있는 거 보이시죠?
이렇게 compile time에 MessageBox를 MessageBoxA로 바꾸고.. 나중에 link할 때도 user32.lib에 있는 정보를 읽고 user32.dll과 연결시켜 주는 것이지요.
( 물론 unicode로 build하셨다면 MessageBoxW.. )
visual studio 6.0 tool인가에 보면 dependency viewer라는 것이 있습니다.
그걸로 위의 source로 build된 exe를 보시면 user32.dll의 MessageBoxA를 쓴다는 걸 쉽게 아실 수 있을 것입니다. 유용한 tool이죠..
설명이 좀 길어졌군요..
도움이 되셨길..