Можно ли определить какой-то макрос в заголовочный файл, используя некоторые настройки проекта или опции makefile? - PullRequest
1 голос
/ 12 февраля 2010

Можно ли добавить #define _MYDEFINE_ в мой заголовочный файл на основе некоторых параметров в настройках проекта. Например: предположим, что в моем файле заголовка (который поставляется вместе с библиотекой) у меня есть несколько макросов, как показано ниже:

#ifdef _MYDEFINE_
#define ABC 2
#else
#define ABC 4
#endif

Теперь, когда я создаю свою библиотеку, я могу добавить _MYDEFINE_ в мои настройки, но я не хочу, чтобы пользователь библиотеки добавил _MYDEFINE_ в свои настройки проекта или код. Вместо этого я хочу, чтобы "#define _MYDEFINE_" автоматически добавлялось в начало заголовка.

Примечание: #define _MYDEFINE_ должен добавляться только тогда, когда это определено в моих настройках препроцессора. Для других настроек он не должен добавляться.

Если это невозможно в настройках проекта, есть ли какие-нибудь инновационные способы сделать это? Любые идеи приветствуются.

Ответы [ 4 ]

4 голосов
/ 12 февраля 2010

Большинство компиляторов C принимают опцию -D для определения символа:

gcc -D_MYDEFINE_ file.c

В этой форме оно неявно установлено в единицу. В противном случае можно явно установить значение:

gcc -D_MYDEFINE_=4 file.c

Допускается несколько -D, даже в операционных системах, которые затрудняют это (например, VMS).

gcc -DSYMBOL1 -DSYMBOL2 -DSYMBOL3 file.c

Они ведут себя так, как будто соответствующие операторы #define появляются перед первой строкой каждого файла командной строки.

#define SYMBOL1 1  (these are virtually present due to command line -D options)
#define SYMBOL2 1
#define SYMBOL3 1

(actual source code begins)
/*
 * file.c:  
 */
#include <ctype.h>
#include <stdlib.h>
 ...
2 голосов
/ 13 февраля 2010

Возможно, вам следует подумать о том, какое влияние _MYDEFINE_ оказывает на вашу библиотеку.

Если вы хотите, чтобы его эффекты были только для разработки (например, NDEBUG), использование опции компилятора -D или /D может быть приемлемым.

Если это имеет эффект, который будет влиять на то, что происходит, когда ваши пользователи используют библиотеку, вам может потребоваться сделать что-то более сложное. В последнем случае вы будете создавать две версии вашей библиотеки, и вы можете назвать их так: как в libX-ABC2.a и libX-ABC4.a. Вам также понадобятся две версии ваших включаемых файлов, и вам может потребоваться сгенерировать заголовки конфигурации с _MYDEFINE_, определенным соответствующим образом в каждой. Если ваша библиотека установлена, вам могут потребоваться каталоги включенных версий для файлов заголовков.

Если, например, _MY_DEFINE_ влияет на расположение объявленных структур или размер объявленного массива в других заголовках, если пользователи включают заголовок для #define ABC 4 в библиотеку, которая предполагает #define ABC 2, вы будете вносить некоторые неприятные ошибки для ваших пользователей, чтобы выследить.

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

1 голос
/ 25 февраля 2010

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

0 голосов
/ 12 февраля 2010

Вы, похоже, ищете флаг компилятора "/ D" (один из немногих, который идентичен почти каждому компилятору C на планете). Использование будет примерно таким: cc /D_MYDEFINE_ myfile.c

В качестве несвязанного, обратите внимание, что имя, такое как _MYDEFINE_, начинающееся с подчеркивания, за которым следует другое подчеркивание или заглавная буква, зарезервировано для реализации - т.е. вы не должны использовать такую ​​вещь.

...