Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save YangSiJun528/a02f428ae9e76aba1e5f1608726eb027 to your computer and use it in GitHub Desktop.

Select an option

Save YangSiJun528/a02f428ae9e76aba1e5f1608726eb027 to your computer and use it in GitHub Desktop.
[Jungle My Note | W06] C언어 관련 툴 정리.md

개념 설명 - GCC와 LLVM

컴파일러의 요소

컴파일러는 보통 프런트엔드, 중간표현(IR), 옵티마이저, 백엔드로 설명한다.

프런트엔드는 소스 코드를 해석해 언어별 구조를 잡고, IR은 분석·최적화·코드 생성을 위해 쓰는 내부 표현이며, 옵티마이저와 백엔드는 이를 다듬어 최종 기계어로 바꾼다.

GCC도 언어별 프런트엔드와 언어 독립적인 중간 단계·백엔드를 가지며, LLVM은 이런 분리를 더 뚜렷하게 드러낸 모듈식 컴파일러 인프라다.

GCC와 LLVM의 역사

GCC는 1987년 GNU C Compiler로 시작했고, 여러 언어를 지원하면서 GNU Compiler Collection으로 확장됐다.

LLVM은 일리노이대 연구 프로젝트에서 출발해 2003년 공개됐고, 지금은 IR·옵티마이저·코드 생성기와 Clang 같은 하위 프로젝트를 포함하는 컴파일러 생태계로 성장했다.

GCC 생태계 vs LLVM 생태계

GCC는 여러 언어용 컴파일러를 하나의 프로젝트 안에서 함께 제공하는 전통적인 통합형 툴체인에 가깝다.
그래서 새 언어를 제대로 지원하려면 GCC 내부 구조에 맞는 프런트엔드를 붙이고, 빌드·유지보수 흐름에도 함께 들어가야 하는 경우가 많다.
(새 언어를 GCC “안에” 넣는 느낌)

반면 LLVM은 최적화기와 코드 생성기 같은 기능을 외부 프로젝트가 비교적 독립적으로 가져다 쓸 수 있게 만든 재사용 가능한 컴파일러 인프라에 가깝다. 그래서 새 언어를 만들 때는 프런트엔드는 별도 프로젝트로 구현하고, 코드 생성과 최적화에는 LLVM을 활용하는 방식이 흔하다.
(별도 컴파일러 프로젝트가 따로 있고, LLVM 라이브러리를 가져다 쓰는 느낌)

이 차이는 새 언어 구현에서 LLVM 계열이 자주 선택되는 이유 중 하나다.
실제 선택에는 기존 툴체인, 빌드 의존성, 유지보수 비용,타깃 플랫폼 지원 같은 현실적인 요소도 크게 작용한다.

실제 언어로 예들 들면, Rust는 보통 LLVM으로 코드 생성을 하고,
Zig는 여러 코드 생성 백엔드를 가지며 현재 널리 쓰이는 주 백엔드는 LLVM이지만 자체 백엔드들도 함께 발전 중이다.
Go는 기본적으로 자체 컴파일러 gc를 쓰지만, GCC 프런트엔드인 gccgo도 공식적으로 존재한다.

C언어 관련 도구 자료 모음

컴파일러 (GCC / LLVM)

빌드 도구 (CMake)

디버거 (GDB / LLDB)

메모리 검사 (Valgrind / AddressSanitizer)

ADT 테스트 관련

과제는 이미 대부분 구현된 코드를 활용하는 느낌이라, 여기서는 ADT 자체를 새로 설계하고 검증하기보다 “이 입력을 넣으면 이런 출력이 나와야 한다” 정도로 테스트를 고민하면 될 듯함.

처음엔 자료구조를 직접 구현하고 여러 방식으로 테스트하는 과제인 줄 알아서, 아래 자료들처럼 ADT 요구사항을 정리하고 엣지 케이스나 랜덤 입력까지 넣어보며 검증하는 방향도 생각했음. 그런데 이번 과제는 그렇게까지 할 필요는 없어 보였음. 하려면 할 수는 있는데, 과제에서 기본 구현이 이미 주어져 있는데 굳이?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment