개요
Ubuntu 환경에서 C 전처리기인 cpp 명령어의 핵심 개념과 동작 방식을 단계별 실습으로 살펴봅니다. 매크로 확장, 조건부 컴파일 디버깅, 인클루드 경로 지정 등 실무 빌드 과정에서 유용한 전처리 기법을 체계적으로 다룹니다.
cpp 명령어 설치 확인 및 기본 버전 점검
cpp 명령어 실습 환경을 구성하기 위해 apt-get update -qq && apt-get install -y gcc 명령어를 실행하여 GCC 패키지를 설치합니다.

which cpp 명령어를 실행하여 시스템 내에 C 전처리기(cpp) 실행 파일이 위치한 경로를 확인합니다.
출력된 /usr/bin/cpp 경로를 통해 시스템 표준 실행 파일 디렉터리에 정상적으로 심볼릭 링크 또는 바이너리가 등록되었음을 알 수 있습니다.

cpp --version 명령어를 실행하여 설치된 GNU C 전처리기의 세부 버전과 빌드 정보를 점검합니다.
Ubuntu 시스템에 13.3.0 버전의 cpp가 정상적으로 설치되어 사용할 준비가 완료되었음을 확인할 수 있습니다.
⚙️ [주요 옵션]
-D name : 지정한 매크로를 정의하여 소스코드 내 조건부 컴파일이나 상수 치환에 사용합니다.-U name : 시스템 기본 또는 이전에 정의된 특정 매크로 정의를 해제합니다.-I dir : 헤더 파일(#include)을 검색할 추가 디렉터리 경로를 지정합니다.-dM : 전처리 과정에서 유효한 모든 매크로 정의 목록을 추출하여 출력합니다.-dD : #define 매크로 정의문과 전처리된 소스코드를 동시에 출력합니다.-P : 전처리 결과물에서 디버깅용 줄 번호 마커(#line) 생성을 억제합니다.-v : 헤더 파일 기본 검색 경로와 전처리기 세부 동작 과정을 상세히 출력합니다.

기본 매크로 치환 및 코드 확장 실습
cpp 명령어 실습을 위한 전용 작업 디렉터리를 생성하고 해당 위치로 이동하기 위해 mkdir -p ~/cpp_practice && cd ~/cpp_practice 명령어를 실행합니다.

매크로 상수와 함수형 매크로 치환을 테스트할 예제 C 소스 코드를 생성하기 위해 printf '#define BUFFER_SIZE 1024\n#define SQUARE(x) ((x) * (x))\nint limit = BUFFER_SIZE;\nint area = SQUARE(5);\n' > macro_test.c 명령어를 실행합니다.

cpp macro_test.c output.i 명령어를 실행하여 C 소스 파일의 매크로를 전처리하고 그 결과를 output.i 파일로 저장합니다.
소스 코드 내 매크로 정의문과 참조 코드가 전처리기를 거쳐 최종 확장된 형태의 파일로 생성됩니다.

cat output.i | grep -v '^#' 명령어를 실행하여 전처리 결과 파일에서 줄 번호 마커(#) 행을 제외하고 실제 확장된 소스 코드만 출력합니다.BUFFER_SIZE 상수가 1024로 치환되고 SQUARE(5) 매크로 함수가 ((5) * (5)) 수식 형태로 정확히 치환 및 확장되었음을 확인할 수 있습니다.

외부 매크로 주입 및 조건부 컴파일 검증 (-D, -U 옵션)
cpp 명령어 실습을 이어가기 위해 작업 디렉터리로 이동하는 cd ~/cpp_practice 명령어를 실행합니다.

조건부 컴파일 분기 동작을 테스트할 예제 C 소스 코드를 생성하기 위해 printf '#ifdef DEBUG\nconst char *status = "DEBUG_ENABLED";\n#else\nconst char *status = "PRODUCTION";\n#endif\n' > condition_test.c 명령어를 실행합니다.

cpp -DDEBUG -P condition_test.c 명령어를 실행하여 명령줄에서 DEBUG 매크로를 정의하고 줄 번호 마커 없이 전처리 결과를 출력합니다.-D 옵션으로 주입된 DEBUG 매크로에 의해 #ifdef 조건문이 참으로 처리되어 const char *status = "DEBUG_ENABLED"; 코드가 선택되어 출력됩니다.

cpp -UDEBUG -P condition_test.c 명령어를 실행하여 DEBUG 매크로 정의를 해제한 상태로 전처리를 진행합니다.-U 옵션으로 인해 매크로가 정의되지 않아 #else 분기가 활성화되면서 const char *status = "PRODUCTION"; 코드가 정상적으로 출력됨을 확인할 수 있습니다.

헤더 인클루드 경로 지정 및 불필요한 라인마커 제거 (-I, -P 옵션)
헤더 인클루드 실습을 진행하기 위해 기존 작업 디렉터리로 이동하는 cd ~/cpp_practice 명령어를 실행합니다.

사용자 정의 헤더 파일을 분리하여 보관할 디렉터리를 생성하기 위해 mkdir -p custom_headers 명령어를 실행합니다.

버전 정보를 나타내는 매크로 상수가 정의된 헤더 파일을 생성하기 위해 echo '#define APP_VERSION "1.0.0"' > custom_headers/version.h 명령어를 실행합니다.

외부 헤더 파일을 인클루드하고 정의된 매크로를 참조하는 예제 소스 코드를 생성하기 위해 printf '#include "version.h"\nconst char *ver = APP_VERSION;\n' > main_app.c 명령어를 실행합니다.

cpp -I./custom_headers -P main_app.c 명령어를 실행하여 사용자 정의 헤더 디렉터리를 포함하고 줄 번호 마커를 제거한 전처리 결과를 출력합니다.-I 옵션을 통해 현재 경로에 없는 version.h 헤더를 지정된 디렉터리에서 성공적으로 탐색해 불러오며, -P 옵션으로 불필요한 라인마커 주석이 제거되어 깔끔하게 치환된 const char *ver = "1.0.0"; 코드만 출력됨을 확인할 수 있습니다.

지금까지 우분투 환경에서 cpp 명령어로 C 전처리기 매크로를 분석하고 활용하는 방법을 간단하게 살펴보았습니다.
복잡한 매크로 전개 과정을 직접 확인하며 빌드 이슈와 코드 디버깅을 한층 더 수월하게 해결해 보시기 바랍니다.