У меня есть файл кода C, содержащий следующее:
#include MYHEADER
Я знаю, что такое включение переменных — плохая практика, но это не мой код, я просто хочу его скомпилировать. Я хочу, чтобы переменная MYHEADER имела значение <some_header.h>, а не "some_header.h".
Я пробовал множество способов передать это, но пока ни один из них не помог.
Например. arm-none-eabi-gcc -c -DMYHEADER=<some.h> -o sample.o sample.c не работает,
Я всегда получаю ошибку: #include expects "FILENAME" or \<FILENAME\>. Использование компилятора ARM GCC в Windows.
Пожалуйста, порекомендуйте.
@Chris Крис Это не его собственный код.
Это невозможно с препроцессором C. Я подозреваю, что файл должен быть обновлен с помощью какого-то другого инструмента.
#define MYHEADER <stdio.h> ... #include MYHEADER компилируется с помощью MS VC. Но #define MYHEADER stdio.h... #include <MYHEADER> нет.
TL;DR: Нет (и я пробовал много раз ;-) Обратите внимание, что "some_header.h" работает с трюком MYHEADER. Но IIRC <some_header.h> не будет. Но единственная разница состоит в том, что "some_header.h" будет сканировать текущий каталог в поисках some_header.h, прежде чем делать то, что будет делать <some_header.h>: искать в каталогах -I, искать в некоторых «стандартных» каталогах (например, /usr/include). Итак, если в текущем каталоге (при компиляции) нет some_header.h, разницы нет.
Создайте файл indirect_some_header.h, содержащий (только) #include <some_header.h>, а затем используйте -DMYHEADER = "indirect_some_header.h" (с соответствующими escape-символами для кавычек для вашей оболочки)
@Barmar: «Это невозможно с препроцессором C»: Да, это возможно. В C 2018 6.10.2 4 говорится: «Директива предварительной обработки формы ##include pp-tokens new-line (которая не соответствует ни одной из двух предыдущих форм) разрешена. Токены предварительной обработки после include в директиве обрабатываются так же, как и в обычном тексте. (Каждый идентификатор, определенный в настоящее время как имя макроса, заменяется списком замещающих токенов предварительной обработки.)…»
Рассматривает ли ваш процессор командной строки < и > как перенаправление файлов? Что произойдет, если поставить -DMYHEADER=<some.h> в кавычки?
проверьте свою папку, там будет файл с именем -o, и gcc получит входные данные от какого-то, возможно, несуществующего some.h и проигнорирует его
@phuclv: Если some.h не существует, оболочка должна сообщить об этом как об ошибке и не выполнять команду. Вероятно, у них в каталоге есть файл some.h.





Сообщение, которое вы получаете, создается GCC, если MYHEADER определен как пустой (в его списке замены нет токенов). Если процессор командной строки (также называемый оболочкой), который вы используете, принимает <some.h> для обозначения перенаправления файла, где < указывает на получение входных данных от some.h, а > принимает следующий за ним -o для обозначения записи в -o, то он оставляет -DMYHEADER= с пустой список замены.
Если это так, исправлением может быть цитирование переключателя:
arm-none-eabi-gcc -c "-DMYHEADER=<some.h>" -o sample.o sample.c
Вот два теста в дополнение к использованию приведенной выше команды:
Проверьте, есть ли в вашем каталоге файл с именем -o. Если это так, то это было создано косвенно, подтверждая, что именно это и происходит.
Создайте файл с именем x.c, поместите в него MYHEADER (и ничего больше) и выполните arm-none-eabi-gcc -E x.c -DMYHEADER=<some.h>. Если процессор командной строки жалуется на отсутствие имени файла после >, это подтверждает гипотезу. Если он выполнит команду или если он выполнит команду после того, как вы добавите, скажем, foo после >, выходные данные покажут, на что заменяется MYHEADER. (Переключатель -E запрашивает предварительную обработку, поэтому единственная строка, содержащая MYHEADER, будет заменена пустой строкой, если -DMYHEADER= будет передана в GCC.)
Одна из проблем с этой гипотезой заключается в том, что процессор командной строки должен был сообщить, что не может открыть some.h для перенаправления ввода. Но, возможно, у вас в каталоге есть файл с таким именем, который удовлетворит процессор командной строки.
Другая возможность заключается в том, что стандарт C не полностью определяет, как обрабатываются токены, полученные в результате замены макроса в #include. Когда <name.h> появляется непосредственно в #include, он обрабатывается специальным грамматическим токеном — последовательностью h-символов. Когда вместо этого используется замена макроса, в стандарте C 2018 6.10.2 4 говорится:
… Метод, с помощью которого последовательность токенов предварительной обработки между парой токенов предварительной обработки
<и>или парой символов"объединяется в один токен предварительной обработки имени заголовка, определяется реализацией.
Я не думаю, что проблема в этом, поскольку тест Compiler Explorer показывает, что GCC обрабатывает замену MYHEADER на <stdio.h> обычным подходящим способом.
Спасибо, Эрик, я бы этого не понял.
Добавление #define MYHEADER <some_header.h> перед #include MYHEADER может сработать.
или
Если у вас много таких, вы можете поместить все #define в файл file.txt и #include этот файл.txt перед использованием #inclue MYHEADER.
почему ты хочешь сделать это? В чем проблема XY?