CFLAGS против CPPFLAGS

Я понимаю, что CFLAGS (или CXXFLAGS для С++) предназначены для компилятора, тогда как CPPFLAGS используется препроцессором.

Но я до сих пор не понимаю разницы.

Мне нужно указать путь включения для файла заголовка, который включен в #include, потому что #include является директивкой препроцессора, является ли препроцессор (CPPFLAGS) единственным, что меня волнует?

В каких обстоятельствах мне нужно предоставить компилятору дополнительный путь include?

В общем случае, если препроцессор находит и включает необходимые файлы заголовков, зачем ему нужно рассказывать о дополнительных каталогах include? Какое использование CFLAGS вообще?

(В моем случае я действительно обнаружил, что ОБА из них позволяют мне скомпилировать мою программу, что добавляет к путанице... Я могу использовать CFLAGS ИЛИ CPPFLAGS для достижения моей цели (по крайней мере, в контексте autoconf). Что дает?)

Ответ 1

Неявное правило make для компиляции программы C

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o [email protected] $<

где синтаксис $() расширяет переменные. Поскольку в вызове компилятора используются как CPPFLAGS, так и CFLAGS, которые вы используете для определения include paths, это вопрос личного вкуса. Например, если 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

Разница между двумя вступает в игру, когда у вас есть несколько языков, которым нужен один и тот же путь include, например, если у вас есть 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

поскольку неявное правило С++ также использует переменную CPPFLAGS.

Это различие дает вам хорошее руководство для использования - если вы хотите, чтобы флаг использовался для всех языков, поместите его в CPPFLAGS, если он для определенного языка поместил его в CFLAGS, CXXFLAGS и т.д. Примеры последнего типа включают стандартные флаги соответствия или предупреждения - вы не хотели бы передавать -std=c99 вашему компилятору С++!

В конечном итоге вы можете сделать что-то подобное в своем файле makefile

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

Ответ 2

Макрос CPPFLAGS используется для указания каталогов #include.

Оба CPPFLAGS и CFLAGS работают в вашем случае, потому что правило make (1) объединяет как предварительную обработку, так и компиляцию в одной команде (поэтому оба макроса используются в команде).

Вам не нужно указывать . как каталог include, если вы используете форму #include "...". Вам также не нужно указывать стандартный каталог компилятора include. Вам нужно указать все остальные include-каталоги.