[C++] Compile Process

chooha·2025년 9월 29일

C++

목록 보기
9/23

📚 C++ 컴파일 과정

🔸 컴파일 과정

  • 전처리기(Pre-processor) : #include, #define 같은 부분을 처리함
  • 컴파일러(Compiler) : 코드 파일을 번역해 obj파일(translation unit)로 생성함
  • 링커(Linker) : 각각의 translation unit을 연결해 실행파일을 생성함

🔸 링키지 과정 (Linkage Process)

  • extern 키워드
    - 해당 식별자의 정의(심볼)가 현재 번역 단위 파일 바깥쪽에 있다고 링커에게 알려줌
    - 전역 함수, 변수는 기본적으로 extern 키워드가 붙었다고 간주됨

  • static 키워드
    - 자신의 translation unit 안에서만 접근이 가능하게 만드는 키워드임
    - internal linkage 방법으로 unnamed namespace를 더 권장하는 듯

🔸 C와의 호환성

  • extern "C" 키워드
    - C++ 소스에서 선언한 전역변수나 함수를 C에서 사용해야 할 경우 사용함
    - 이 키워드를 붙이면 네임 맹글링을 진행하지 않음
    - C 인터페이스를 가진 심볼로 생성됨 (함수 오버로딩도 불가능해짐)

    네임 맹글링(Name Mangling)

    • C++에서 지원하는 함수 오버로딩을 구현하기 위해 사용되는 심볼 작명 방식임
    • 컴파일 시 함수 이름을 고유하게 변경하여 같은 이름의 다른 함수들을 구분함

🔸 어셈블리 코드와 최적화

성능에 대한 오해

  • multiply 연산보다 shift bit 연산이 더 빠르다고 알려져 있지만, 실제 어셈블리어로 변환해보면 똑같음 (최신 컴파일러에서는 최적화를 통해 비슷한 성능을 보이는 경우가 많음)
  • 어셈블리어가 더 짧다고 더 빠른 것은 아님
  • if/else문과 switch문도 똑같음
  • 이런 이유들로 가독성이 좋은 코드를 선택하는 것이 좋음

🔸 디버깅과 최적화

디버그 옵션

  • -g 옵션 : debug info가 포함됨
  • debug info는 binary(machine code)와 cpp source를 연결해주는 디버깅용 메타 데이터임(소스 코드 줄 번호, 변수명, 타입 정보 등 포함)
  • -o 옵션 : optimization을 진행함

🔸 라이브러리 종류

라이브러리 유형

  • Header only : 헤더 파일만으로 구성됨
  • Static library : 윈도우는 .lib / 리눅스는 .a 파일
  • Dynamic library : 윈도우는 .dll / 리눅스는 .so 파일

🔹 Static Library

정의와 생성

  • 오브젝트 파일을 모아서 하나의 아카이브 파일을 만듦
  • 생성법: ar -rs libcat.a cat.o (cat.h에 대한 라이브러리 생성 시)

사용법

  • g++ main.cpp -lcat으로 사용하지만 이렇게 하면 libcat.a파일이 표준 라이브러리 경로에 없어서 에러 발생함
  • 해결법: -L 옵션을 붙여야 함 (특정 위치에서 libcat.a파일을 찾아서 적용)
  • -L.이면 현재 디렉토리 위치를 의미함

🔹 Dynamic Library (Shared Library)

바인딩 타이밍

  • Load time dynamic library : 로드 타임에 라이브러리가 바인딩됨
  • Run time dynamic library : 런타임에 라이브러리가 바인딩됨
  • Static은 exe파일이 만들어질 때 바인딩됨
  • Run time은 특정 조건에서만 사용하고, 보통은 Load time을 씀

Load Time Dynamic Library 생성

g++ foo.cpp -fPIC -c
g++ -shared foo.o -o libfoo.so

-fPIC 옵션의 필요성

  • shared library가 여러 어플리케이션, 프로세스에서 실행되어야 함
  • -fPIC 옵션을 주지 않으면 absolute base address가 되어 서로 다른 앱에서 주소를 지정할 수 없음
  • -fPIC 옵션을 주면 relative base address를 가져서 각각의 어플에서 로드되고 호출될 수 있음

Run Time Dynamic Library 사용
런타임에 동적으로 라이브러리를 로드하고 함수를 호출하는 코드를 작성할 수 있음. 이를 위해서는 <dlfcn.h> 헤더를 포함하고 dlopen, dlsym, dlclose 함수들을 사용하여 라이브러리를 동적으로 관리할 수 있음

#include <dlfcn.h>

int main()
{
	void* handle = dlopen("./libfoo.so", RTLD_LAZY);
	if(!handle)
	{
		//handle 없음 출력
	}
	void (*fooPtr)();
	fooPtr = (void(*)())dlsym(handle,"_Z3foov");
	
	(*fooPtr)();
	dlclose(handle);
	return 0;
}

<참고 자료>

코드없는 프로그래밍
[C/C++] extern, static

0개의 댓글