Как правильно жестко запрограммировать флаг определения компилятора (-D) с помощью #define в c (arduino)

#c #arduino #compilation #header-files #pre-compilation

#c #arduino #Сборник #заголовочные файлы #предварительная компиляция

Вопрос:

Каков наилучший способ жестко запрограммировать флаг компилятора -D в исходных файлах?

Я хочу поместить #define в один из заголовков, а затем импортировать кучу вещей, которые должны реагировать на это определение. Так ли это работает? В какой заголовок я должен его поместить? Или непосредственно в main.c? Или для всех из них?

TMI-подробности: здесь используется среда digispark hw-018 (attiny85 со встроенным USB-программатором), а #define должен заменить -DUSE_SOFTWARE_SPI, чтобы я мог использовать библиотеку AVR-CAN в режиме SPI для чтения материалов из MCP2515.

РЕДАКТИРОВАТЬ: после некоторого раздражающего удара головой о стену верхняя часть main.c теперь выглядит так, и она по-прежнему не работает.

 #define USE_SOFTWARE_SPI 
#include "src/can.h"
#define USE_SOFTWARE_SPI 
#include <avr/io.h>
#define USE_SOFTWARE_SPI 
#include <avr/pgmspace.h>
#define USE_SOFTWARE_SPI 
#include <DigiUSB.h>
 

Я прав, говоря, что где-то есть что-то, что переопределяет мое определение? Это работает, если я жестко запрограммирую #define USE_SOFTWARE_SPI непосредственно перед #ifndef (или #ifdef)

Комментарии:

1. Почему бы не поместить его в самый верх вашего main.c исходного файла, #include сразу после s? Это дало бы понять всем читателям, что происходит.

2. Смотрите Отличный ответ Стива Фридла ниже (пожалуйста, «поддержите» и «примите», если сочтете это полезным), настройка вашего #define на уровне проекта (например, «makefile» или .csproj) является «идеальной». Разумной альтернативой является отдельный файл .h, который #включает ВСЕ заголовки, которые используют этот #define . Размещение вашего #define в верхней части вашего .c является самым простым. Если это «одноразовый» проект, если у вас есть только один исходный файл, и если он работает для вас — дерзайте 🙂

3. Это ничем не отличается для Arduino от любой другой платформы. Изучите правильный способ и применяйте его. Существует бесчисленное множество руководств о том, как правильно создавать заголовочные файлы.

4. По какой-то причине я не могу заставить это работать … помещение define в main.c не работает. Я должен поместить его в тот же файл, где есть #ifndef или #ifdef… Я думаю, что кто-то жестко запрограммировал это где-то глубоко…

5. Пожалуйста, не редактируйте решения в вопросе. Создайте ответ самостоятельно или, пожалуйста, примите один из существующих ответов.

Ответ №1:

Здесь есть несколько подходов.

Если это всего лишь один main.c исходный файл, то можно поместить его в начало файла:

 // main.c
#define USE_SOFTWARE_SPI // must be first!
#include <spi_stuff.h>
...
 

Это плохо масштабируется, если это должно быть в нескольких исходных файлах, потому что слишком легко пропустить его в одном из нескольких мест.

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

Я предпочитаю включать подобные вещи в определение проекта в целом, либо в makefile IDE, либо в то, что IDE использует для управления проектом, потому что это гарантирует, что все это видят.

Итак, если у вас есть несколько исходных файлов, и вы не можете или не хотите помещать это в файл проекта, тогда способ справиться с этим — использовать ваш собственный пользовательский заголовок, который существует только для этой цели:

 // my_spi_stuff.h
#define USE_SOFTWARE_SPI 
#include <spi_stuff.h>
... others if needed
 

а затем включите это в свои .c программы. Обязательно укажите файлу имя, которое настоятельно предполагает «локальные настройки», а не что-то, что можно спутать с именем, предоставляемым библиотекой.

РЕДАКТИРОВАТЬ Я только что перечитал, что это Arduino, и, насколько я знаю, в IDE нет настроек для всего проекта.

Комментарии:

1. У меня возникла проблема с передачей #define … Правильно ли я понял это в отредактированном вопросе?

2. Хорошо, теперь я понял. #define означает «модуль компиляции», поэтому, если я компилирую библиотеку, заголовок библиотеки должен содержать #define в дополнение к main.c. Обычно я бы поместил это в глобальные CFLAGS в Makefile, теперь в каждом первом заголовке для каждого «модуля компиляции». Не могли бы вы добавить это примечание в конец.

3. Я думаю, что я описал это; в любом месте, где используется заголовок библиотеки, вам нужно #define перед ним. В некоторых программах это может быть просто main.cpp , но если вы используете заголовок в каком-то другом модуле компиляции, вам нужно сделать то же самое там. Это то, что ты говоришь?

4. да, в основном это. В простой программе верхняя часть main.c в порядке, но если вы компилируете библиотеки, каждый заголовок библиотеки должен иметь его в начале. Для обычного пользователя C (например, меня) это неясно, поскольку -D в cflags в Makefile делает это автоматически для всех. Короче говоря: «Какой заголовок я должен поместить? — Каждый заголовок каждого модуля компиляции. »