전처리 옵션
전처리 옵션 (Preprocessing Options)
Fortran 소스 코드를 조건부 컴파일할 수 있게 C 전처리기(CPP)를 통과시키는 방법과, 그때 쓰는 옵션들을 설명해요. 어떤 확장자를 가진 파일이 자동으로 전처리되는지부터, -cpp/-nocpp로 수동 제어하는 법, 그리고 전처리 단계를 세밀하게 다루는 여러 옵션까지 정리돼 있어요.
본문
많은 Fortran 컴파일러—GNU Fortran을 포함해서—는 조건부 컴파일을 지원하기 위해 소스 코드를 C 전처리기(CPP; 때로는 Fortran 전처리기 FPP라고도 불러요)에 통과시킬 수 있게 해 줘요. GNU Fortran의 경우 전통적인(traditional) 모드의 GNU C 전처리기를 사용해요. 대소문자를 보존하는 파일명을 쓰는 시스템에서는, 파일 확장자가 .F, .FOR, .FTN, .fpp, .FPP, .F90, .F95, .F03 또는 .F08이면 전처리기가 자동으로 호출돼요. 어떤 파일에든 전처리기를 수동으로 호출하려면 -cpp를 쓰고, 자동으로 실행되는 파일에서 전처리를 끄려면 -nocpp를 써요.
전처리된 파일을 컴파일할 때는 -fpreprocessed를 사용해요 (Using the GNU Compiler Collection (GCC)의 Options Controlling the Preprocessor 참고). 이 옵션은 C 전처리기를 건너뛰게 해요.
전처리된 파일이 Fortran INCLUDE 문으로 다른 파일을 포함한다면, 포함된 파일은 전처리되지 않아요. 포함 파일까지 전처리하고 싶다면 그에 해당하는 전처리기 문 #include를 쓰면 돼요.
GNU Fortran이 전처리기를 호출하면 __GFORTRAN__이 정의돼요. __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__ 매크로로 컴파일러 버전을 알아낼 수 있어요. 자세한 내용은 The C Preprocessor의 Overview 부분을 참고하면 돼요.
GNU Fortran은 Fortran 표준이 요구하는 종류(kind) 외에도 여러 INTEGER와 REAL 종류를 지원해요. 특정 종류가 있는지는 아키텍처에 따라 달라져요. 다음의 미리 정의된 전처리기 매크로로 이런 추가 종류를 위한 코드를 조건부로 넣을 수 있어요: __GFC_INT_1__, __GFC_INT_2__, __GFC_INT_8__, __GFC_INT_16__, __GFC_REAL_10__, __GFC_REAL_16__.
CPP가 Fortran 전처리의 사실상 표준(de facto standard)인 반면, Fortran 95 표준 3부(ISO/IEC 1539-3:1998)는 조건부 컴파일(Conditional Compilation)을 정의하는데, 이는 널리 쓰이지 않고 GNU Fortran 컴파일러가 직접 지원하지도 않아요.
다음 옵션들이 Fortran 코드의 전처리를 제어해요.
-cpp -nocpp
전처리를 활성화해요. 파일 확장자가 .fpp, .FPP, .F, .FOR, .FTN, .F90, .F95, .F03 또는 .F08이면 전처리기가 자동으로 호출돼요. 이 옵션으로 어떤 종류의 Fortran 파일이든 전처리를 수동으로 켤 수 있어요.
위 확장자를 가진 파일의 전처리를 끄려면 반대 형태인 -nocpp를 쓰면 돼요.
전처리기는 전통적인(traditional) 모드로 실행돼요. 파일 형식의 제약—특히 행 길이 제한—은 전처리된 출력에도 그대로 적용되므로, -ffree-line-length-none나 -ffixed-line-length-none 옵션을 쓰는 것이 좋을 때가 있어요.
-dM
일반적인 출력 대신, 전처리기 실행 동안 정의된 모든 매크로(미리 정의된 매크로 포함)에 대한 '#define' 지시문 목록을 생성해요. 이렇게 하면 여러분 버전의 전처리기에 무엇이 미리 정의되어 있는지 알아낼 수 있어요. foo.f90 파일이 없다고 가정하면,
touch foo.f90; gfortran -cpp -E -dM foo.f90
이 명령이 모든 미리 정의된 매크로를 보여 줘요.
-dD
-dM과 비슷하지만 두 가지 점이 달라요: 미리 정의된 매크로를 포함하지 않고, #define 지시문과 전처리 결과를 모두 출력해요. 두 종류의 출력 모두 표준 출력 파일로 나가요.
-dN
-dD와 같지만, 매크로 이름만 내보내고 그 확장 값은 내보내지 않아요.
-dU
dD와 같지만, 전처리기 지시문에서 확장되거나 정의 여부가 검사된 매크로만 출력돼요. 출력은 매크로가 사용되거나 검사될 때까지 지연되고, 검사 시점에 정의되지 않았던 매크로에 대해서는 '#undef' 지시문도 함께 출력돼요.
-dI
전처리 결과에 더해 '#include' 지시문도 출력해요.
-fworking-directory
전처리기 출력에 linemarker를 생성해서, 전처리 당시의 현재 작업 디렉토리를 컴파일러가 알 수 있게 해 줘요. 이 옵션을 켜면 전처리기는 첫 linemarker 다음에 현재 작업 디렉토리와 두 개의 슬래시가 붙은 두 번째 linemarker를 출력해요. 전처리된 입력에 이 디렉토리가 있으면, GCC는 일부 디버깅 정보 형식에서 현재 작업 디렉토리로 방출되는 디렉토리로 이것을 사용해요. 이 옵션은 디버깅 정보가 활성화되면 암시적으로 켜지지만, 반대 형태인 -fno-working-directory로 막을 수 있어요. 명령줄에 -P 플래그가 있으면 #line 지시문이 전혀 생성되지 않으므로 이 옵션은 효과가 없어요.
-idirafter dir
dir에서 include 파일을 찾되, -I로 지정된 모든 디렉토리와 표준 시스템 디렉토리를 모두 소진한 뒤에 찾아요. dir은 시스템 include 디렉토리로 취급돼요. dir이 =로 시작하면 =는 sysroot 접두사로 대체돼요. --sysroot와 -isysroot를 참고해요.
-imultilib dir
dir을 대상별 C++ 헤더가 들어 있는 디렉토리의 하위 디렉토리로 사용해요.
-iprefix prefix
이후의 -iwithprefix 옵션들을 위한 접두사로 prefix를 지정해요. prefix가 디렉토리를 나타내면 마지막 '/'를 포함해야 해요.
-isysroot dir
이 옵션은 --sysroot 옵션과 같지만 헤더 파일에만 적용돼요. 자세한 내용은 --sysroot 옵션을 참고해요.
-iquote dir
#include "file"로 요청된 헤더 파일에 대해서만 dir을 검색해요. #include <file>에는 적용되지 않아요. 이때 -I로 지정된 모든 디렉토리와 표준 시스템 디렉토리보다 먼저 검색해요. dir이 =로 시작하면 =가 sysroot 접두사로 대체돼요. --sysroot와 -isysroot를 참고해요.
-isystem dir
-I로 지정된 모든 디렉토리 다음, 표준 시스템 디렉토리 이전에 dir에서 헤더 파일을 검색해요. 이 디렉토리를 시스템 디렉토리로 표시해서 표준 시스템 디렉토리와 똑같은 특별 취급을 받게 해요. dir이 =로 시작하면 =가 sysroot 접두사로 대체돼요. --sysroot와 -isysroot를 참고해요.
-nostdinc
헤더 파일에 대해 표준 시스템 디렉토리를 검색하지 않아요. -I 옵션(그리고 적절하다면 현재 파일의 디렉토리)으로 지정한 디렉토리만 검색돼요.
-undef
시스템 특화 또는 GCC 특화 매크로를 미리 정의하지 않아요. 표준 미리 정의 매크로는 정의된 채로 남아요.
-Apredicate=answer
predicate 술어와 answer 답을 사용해 assertion을 만듭니다. 이 형식은 여전히 지원되는 예전 형식 -A predicate(answer)보다 선호되는데, 셸 특수 문자를 사용하지 않기 때문이에요.
-A-predicate=answer
predicate 술어와 answer 답을 사용한 assertion을 취소해요.
-C
주석을 버리지 않아요. 모든 주석은 처리된 지시문 안의 주석을 제외하고 출력 파일로 통과돼요. 지시문 안의 주석은 지시문과 함께 삭제돼요.
-C를 쓰면 부작용이 있을 수 있다는 점을 알아 둬야 해요. -C는 전처리기가 주석을 그 자체로 하나의 토큰으로 취급하게 해요. 예를 들어 지시문 행의 시작에 나타나는 주석은, 그 행의 첫 토큰이 더 이상 '#'이 아니게 되므로 그 행을 평범한 소스 행으로 바꿔 버려요.
경고: -C는 현재 C 스타일 주석만 처리해요. 전처리기는 아직 Fortran 스타일 주석을 인식하지 못해요.
-CC
매크로 확장 중에도 주석을 버리지 않아요. -C와 같지만, 매크로 안에 포함된 주석도 매크로가 확장되는 곳에서 출력 파일로 통과돼요.
-C 옵션의 부작용에 더해, -CC 옵션은 매크로 안의 모든 C++ 스타일 주석을 C 스타일 주석으로 변환해요. 이는 이후에 그 매크로를 사용할 때 소스 행의 나머지가 실수로 주석 처리되는 것을 막기 위해서예요. -CC 옵션은 일반적으로 lint 주석을 지원하는 데 쓰여요.
경고: -CC는 현재 C 및 C++ 스타일 주석만 처리해요. 전처리기는 아직 Fortran 스타일 주석을 인식하지 못해요.
-Dname
name을 값 1의 매크로로 미리 정의해요.
-Dname=definition
definition의 내용은 토큰화되어, 번역 3단계(translation phase three)에서 '#define' 지시문에 나타나는 것처럼 처리돼요. 특히 정의는 포함된 줄바꿈 문자에 의해 잘려요.
셸이나 셸류 프로그램에서 전처리기를 호출한다면, 셸 문법에서 의미를 갖는 공백 같은 문자를 보호하기 위해 셸의 인용(quoting) 문법을 사용해야 할 수도 있어요.
명령줄에서 함수형 매크로를 정의하고 싶다면, 등호 앞에 인자 목록을 괄호로 감싸 작성해요 (적절한 경우). 괄호는 대부분의 셸에 의미가 있으므로 옵션을 인용해야 해요. sh와 csh에서 -D'name(args...)=definition'가 동작해요.
-D와 -U 옵션은 명령줄에 주어진 순서대로 처리돼요. 모든 -imacros file과 -include file 옵션은 모든 -D와 -U 옵션 다음에 처리돼요.
-H
일반적인 활동에 더해 사용된 각 헤더 파일의 이름을 출력해요. 각 이름은 '#include' 스택에서 얼마나 깊은지 보여 주도록 들여쓰기돼요.
-P
전처리기 출력에서 linemarker 생성을 막아요. C 코드가 아닌 것을 전처리하고, 그 결과를 linemarker에 혼란스러워할 수 있는 프로그램에 보낼 때 유용할 수 있어요.
-Uname
이전의 name 정의를 취소해요—내장이든 -D 옵션으로 제공된 것이든.
더 알아보기
- Error and Warning Options — 오류·경고 요청/억제 옵션
- Options Controlling the Preprocessor (GCC) — GCC C 전처리기 옵션 상세
- The C Preprocessor Overview — C 전처리기 매뉴얼