CFLAGS, CCFLAGS, CXXFLAGS - чим саме керують ці змінні?


76

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

Я читаю в різних місцях CFLAGS, CCFLAGSі CXXFLAGSдля цього їх використовують. То як я повинен їх використовувати? Якщо у мене є додаткові аргументи командного рядка до компілятора, чи слід додавати їх до них CFLAGSабо додавати до них? Чи існує загальноприйнята практика?

Чому три різні змінні? Я припускаю, що компілятор C повинен отримати CFLAGSі CCFLAGS, тоді як компілятор C ++ повинен отримати CFLAGSі CXXFLAGS- чи правильно я це зрозумів?

Чи повинен користувач-людина взагалі встановлювати ці змінні? Чи є якісь -то автоматичні інструменти ( automake, autoconfі т.д.) , які виводять їх? Система Linux, яку я повинен використовувати, не визначає жодної з цих змінних - це типово?

Наразі мій Makefile виглядає так, і я відчуваю, що він трохи брудний:

Я майже впевнений, що тут немає помилок; Makefile працює дуже добре. Але чи є щось, що суперечить умовам (наприклад, CCFLAGSINT- чи слід просто замінити CCFLAGSзамість цього? Або CXXFLAGS? FUD!)

Вибачте за стільки питань; ви, очевидно, не будете відповідати на всі, але я сподіваюся, що відповіді допоможуть мені зрозуміти загальну ідею цих налаштувань.


Справедливо сказати, на основі цих відповідей, що ці змінні оточення не зміна / не використовуються gccабо clangкомпілятори самі ?
іоносферні

Відповіді:


84

Як ви помітили, це Makefile {макроси або змінні}, а не параметри компілятора. Вони впроваджують набір домовленостей. (Макроси - це стара назва для них, яка все ще використовується деякими. GNU make doc називає їх змінними.)

Єдина причина, що імена мають значення, - це правила за замовчуванням, видимі через make -p, які використовують деякі з них.

Якщо ви пишете всі власні правила, ви можете вибрати усі власні імена макросів.

У складі ванільного гну немає такого поняття, як CCFLAGS. Є CFLAGS, CPPFLAGSі CXXFLAGS. CFLAGSдля компілятора C, CXXFLAGSдля C ++ і CPPFLAGSдля обох.

Чому CPPFLAGSв обох? Звичайно, це будинок прапорців препроцесора ( -D, -U), і як c, так і c ++ використовують їх. Тепер припущення, що всі хочуть однакове середовище визначення для c та c ++, можливо, сумнівне, але традиційне.


PS Як зазначив Джеймс Мур , деякі проекти використовують CPPFLAGS для прапорів до компілятора C ++, а не прапори до препроцесора C. Одним з величезних прикладів є Android NDK.


7
Я підтримав вас за те, що ви трохи помилилися, але ви досить близько, щоб помилитися, і мені не варто робити зовсім окрему відповідь. $(CPPFLAGS)є прапорами для препроцесора. Той факт, що вони використовуються у викликах $(CC)та $(CXX)є випадковим. Крім того, це змінні Makefile, а не макроси.
Джек Келлі,

3
@Jack: GNU Make викликає їх змінними; кілька інших джерел, в тому числі опис UNIX Specification Сингл про косметики , називати їх макроси. Однакові речі.
Джон Маршалл,

2
@Jack у 1982 році, коли я познайомився, вони назвали їх макросами.
bmargulies

4
аі мене ретельно взяли до школи. Спасибі, хлопці.
Джек Келлі,

2
@Jack, ні, ні ні. Я не намагаюся навчати вас у школі, а лише пояснити, звідки вийшов мій особливий погляд. Насправді, слідкуйте за редагуванням ...
bmargulies

13

Відповідно до GNU makeпосібника:

CFLAGS: Додаткові прапори для передачі компілятору C.
CXXFLAGS: Додаткові прапори для передачі компілятору C ++.
CPPFLAGS: додаткові прапори для передачі препроцесору C та програмам, які його використовують (компілятори C та Fortran).

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

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

Ці змінні використовуються за неявними правилами make

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

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

src: https://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules


3

Мінімальний приклад

І лише для того, щоб зробити те, що сказав Мізу, як мінімальний приклад:

main_c.c

main_cpp.cpp

Тоді, без жодних Makefile:

працює:

Отже, ми розуміємо, що:

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

Ці змінні використовуються лише в неявних правилах make автоматично: якби компіляція використовувала наші власні явні правила, тоді нам довелося б явно використовувати ці змінні, як у:

для досягнення подібного впливу на неявні правила.

Ми могли б також називати ці змінні як завгодно: але оскільки Make вже трактує їх магічно в неявних правилах, вони роблять правильний вибір імен.

Протестовано в Ubuntu 16.04, GNU Make 4.1.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.