CFLAGS 대 CPPFLAGS


104

CFLAGS (또는 C ++의 경우 CXXFLAGS)는 컴파일러 용이고 CPPFLAGS는 전 처리기에서 사용된다는 것을 이해합니다.

그러나 나는 여전히 그 차이를 이해하지 못한다.

#include에 포함 된 헤더 파일의 포함 경로를 지정해야합니다.

어떤 상황에서 컴파일러에 추가 포함 경로를 제공해야합니까?

일반적으로 전처리 기가 필요한 헤더 파일을 찾아 포함하는 경우 추가 포함 디렉토리에 대해 알려야하는 이유는 무엇입니까? CFLAGS는 어떤 용도로 사용됩니까?

(제 경우 에는이 두 가지 가 모두 프로그램을 컴파일 할 수있게하여 혼란을 가중시키는 것으로 나타났습니다. CFLAGS 또는 CPPFLAGS를 사용 하여 목표를 달성 할 수 있습니다 (적어도 autoconf 컨텍스트에서). 무엇을 제공합니까?)


답변:


154

C 프로그램을 컴파일하기위한 암시 적 make 규칙은 다음과 같습니다.

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

여기서 $()구 변수를 확장한다. CPPFLAGS및 둘 다 CFLAGS컴파일러 호출에서 사용되므로 포함 경로를 정의하는 데 사용하는 것은 개인적인 취향의 문제입니다. 예를 들어이 foo.c파일이 현재 디렉토리에 있다면

make foo.o CPPFLAGS="-I/usr/include"
make foo.o CFLAGS="-I/usr/include"

둘 다 정확히 같은 방식으로 컴파일러를 호출합니다.

gcc -I/usr/include -c -o foo.o foo.c

같은 필요한 여러 언어가 경로를 포함 때 둘 사이의 차이는 활동하기 시작, 예를 들어 당신이 경우 bar.cpp다음 시도

make bar.o CPPFLAGS="-I/usr/include"
make bar.o CFLAGS="-I/usr/include"

그런 다음 편집은

g++ -I/usr/include -c -o bar.o bar.cpp
g++ -c -o bar.o bar.cpp

C ++ 암시 적 규칙도 CPPFLAGS변수를 사용하므로

이 차이는 당신에게 사용을위한 좋은 가이드를 제공합니다 - 당신은 모든 언어 넣어위한 플래그를 사용하려는 경우 CPPFLAGS, 그것은 특정 언어에 대한의에 넣어 경우 CFLAGS, CXXFLAGS등 후자의 예로는 표준 준수 또는 경고 플래그를 포함 -std=c99-C ++ 컴파일러 에 전달하고 싶지 않을 것입니다 !

그런 다음 makefile에서 이와 같은 결과를 얻을 수 있습니다.

CPPFLAGS=-I/usr/include
CFLAGS=-std=c99
CXXFLAGS=-Weffc++

1
당신은 독립 실행되지 않을 수 있습니다 cpp사용 CPPFLAGS하기 때문에 합리적인 결과를 기대 -std=c99기호 (특히 기능 테스트 매크로 대신에) 정의 된 영향을 미칩니다. 대신 $(CC) $(CPPFLAGS) $(CFLAGS) -E.
Jed

10

CPPFLAGS매크로를 지정하는 데 사용할 수있는 하나입니다 #include디렉토리.

모두 CPPFLAGSCFLAGS귀하의 경우 작업 때문에 make(1) 규칙은 전처리 및 (모두 매크로 명령에 사용되도록) 하나의 명령으로 컴파일을 결합.

.양식을 사용하는 경우 include-directory 로 지정할 필요가 없습니다 #include "...". 또한 표준 컴파일러 포함 디렉터리를 지정할 필요가 없습니다. 다른 모든 include- 디렉토리를 지정해야합니다.


이것은 더 의미가 있지만 CFLAGS가 무엇을하는지 여전히 알 수 없습니다. 암시하는 것처럼 더 복잡한 프로젝트의 컴파일이 전처리와 별도의 단계에서 수행되는 경우 전처리는 성공하지만 CFLAGS가 전처리기에 추가 한 동일한 경로를 추가하지 않으면 컴파일이 실패합니까? 전처리 기가 이미 #include 지시문을 처리했다면 컴파일러가 include 경로로 무엇을하는지 이해하지 못하는 것 같습니다.
EBM

4
@EB 사전 처리 된 파일을 컴파일하는 경우 포함 경로가 필요하지 않습니다. 필요한 헤더가 이미 사전 처리 된 소스에 추가되었습니다 ( gcc -E파일에서 실행할 때 출력을 확인 하십시오-#include가 없음). 대부분의 최신 컴파일러는 사전 처리 및 컴파일 단계를 결합하므로 이에 대해 걱정할 필요가 없습니다.
Scott Wales


0

암시 적 규칙을 언급 한 사람들에게 추가하려면 make가 암시 적으로 정의 된 것과 환경에 대해 다음을 사용하여 확인하는 것이 가장 좋습니다.

make -p

예를 들면 :

%.o: %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

확장되는

COMPILE.c = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

이것은 또한 # environment데이터 를 인쇄 합니다. 여기에서 다른 유용한 정보 중에서 GCC의 포함 경로를 찾을 수 있습니다.

C_INCLUDE_PATH=/usr/include

검색에 관해서는 경로가 많고 빛은 하나입니다.

  1. C_INCLUDE_PATH시스템 전체에 적용되며 셸의 *.rc.
  2. $(CPPFLAGS) 전 처리기 포함 경로입니다.
  3. make에 대한 일반 검색 경로를 추가해야하는 경우 다음을 사용하십시오.
VPATH = my_dir_to_search

... 또는 더 구체적

vpath %.c src
vpath %.h include

make는 VPATH를 일반 검색 경로로 사용하므로 신중하게 사용하십시오. VPATH에 나열된 둘 이상의 위치에 파일이있는 경우 make는 목록에서 첫 번째 항목을 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.