Подтвердить что ты не робот

CFLAGS, CCFLAGS, CXXFLAGS - что именно эти переменные контролируют?

Я использую GNU make для компиляции моего кода на С++, и я хотел бы понять, как сделать мои компиляции настраиваемыми.

Я читал в разных местах, что CFLAGS, CCFLAGS и CXXFLAGS используются для этой цели. Итак, как я должен их использовать? Если у меня есть дополнительные аргументы командной строки для компилятора, я должен добавить их в CFLAGS или добавить их? Существует ли обычная практика?

Почему три разные переменные? Я предполагаю, что компилятор C должен получить CFLAGS и CCFLAGS, тогда как компилятор С++ должен получить CFLAGS и CXXFLAGS - я правильно понял?

Предполагается ли, что пользователь должен установить эти переменные вообще? Устанавливаете ли какие-либо автоматические инструменты (automake, autoconf и т.д.)? Система linux, которую я должен использовать, не определяет ни одну из этих переменных - это типичный?

В настоящее время мой Makefile выглядит так, и я чувствую, что это немного грязно:

ifdef code_coverage
    GCOV_FLAG := -fprofile-arcs -ftest-coverage
else
    GCOV_FLAG :=
endif

WFLAGS := -Wall

INC_FLAGS := -Istuff -Imore_stuff -Ietc

CCFLAGSINT := -O3 $(WFLAGS) $(INC_FLAGS) $(CCFLAGS)

... (somewhere in the makefile, the command-line for compilation looks like this)
    $(CC) $(CCFLAGSINT) -c $< -o [email protected]

... (somewhere in the makefile, the command-line for linking looks like this)
    $(CC) $(GCOV_FLAG) $(CCFLAGSINT) $(OBJLIST) $(LDFLAGS) -o [email protected]

Я уверен, что здесь нет ошибок; Makefile работает очень хорошо. Но есть ли что-либо, что противоречит соглашениям (например, CCFLAGSINT - вместо того, чтобы просто перезаписать CCFLAGS? Или CXXFLAGS? FUD!)

Извините за столько вопросов; вы, очевидно, не ответите им, но я надеюсь, что ответы помогут мне понять общую идею этих настроек.

4b9b3361

Ответ 1

Как вы заметили, это Makefile {макросы или переменные}, а не опции компилятора. Они реализуют ряд соглашений. (Макросы - это старое имя для них, которое до сих пор используется некоторыми. GNU make doc называет их переменными.)

Единственная причина, по которой имена имеют значение, это правила make по умолчанию, видимые через make -p, которые используют некоторые из них.

Если вы пишете все свои собственные правила, вы можете выбрать все свои собственные имена макросов.

В ванильном гну делают, нет такой вещи, как CCFLAGS. Есть CFLAGS, CPPFLAGS и CXXFLAGS. CFLAGS для компилятора C, CXXFLAGS для C++ и CPPFLAGS для обоих.

Почему CPPFLAGS в обоих? Традиционно он является домом флагов препроцессора (-D, -U), и оба c и C++ используют их. Предположение о том, что все хотят одинаковую среду для c и C++, возможно, сомнительно, но традиционно.


PS Как отметил Джеймс Мур, некоторые проекты используют CPPFLAGS для флагов компилятору C++, а не для флагов препроцессора C. Android NDK, для одного огромного примера.

Ответ 2

Согласно GNU make руководство:

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

источник: https://www.gnu.org/software/make/manual/make.html#index-cFLAGS
примечание: PP обозначает PreProcessor (а не Plus Plus), т.е.

CPP: программа для запуска препроцессора C с результатами на стандартный вывод; по умолчанию '$ (CC) -E.

Эти переменные используются неявными правилами make

Компиляция C программ
no сделан автоматически из nc с рецептом формы
'$ (CC) $ (CPPFLAGS) $ (CFLAGS) -c.

Компиляция C++ программ
no производится автоматически из n.cc, n.cpp или nC с рецептом вида
'$ (CXX) $ (CPPFLAGS) $ (CXXFLAGS) -c.
Мы рекомендуем вам использовать суффикс '.cc для исходных файлов C++ вместо'.C.

источник: https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules

Ответ 3

И просто для того, чтобы Mizux сказал как минимальный пример:

main_c.c

#include <stdio.h>

int main(void) {
    puts("hello");
}

main_cpp.cpp

#include <iostream>

int main(void) {
    std::cout << "hello" << std::endl;
}

Тогда без какого-либо Makefile:

make CFLAGS='-g -O3' CXXFLAGS='-ggdb3 -O0' CPPFLAGS='-DX=1 -DY=2' main_c main_cpp

работает:

cc -g -O3 -DX=1 -DY=2   main_c.c   -o main_c
g++ -ggdb3 -O0 -DX=1 -DY=2   main_cpp.cpp   -o main_cpp

Итак, мы понимаем, что:

  • make были неявные правила для создания main_c и main_cpp из main_c.c и main_cpp.cpp
  • CFLAGS и CPPFLAGS использовались как часть неявного правила для компиляции .c
  • CXXFLAGS и CPPFLAGS использовались как часть неявного правила для компиляции .cpp