Могу ли я использовать директивы препроцессора в файле .ld? Мне нужно использовать один из двух наборов файлов .ld, и я хочу, чтобы движок сборки решал это с помощью макроса. Могу ли я это сделать?
3 ответа
Да, ты можешь. Вам нужно вручную запустить препроцессор для вашего сценария компоновщика, например:
in="your_linker_script.ld"
out="generated_script.ld"
cflags=-Iinclude/
gcc -E -x c $cflags $in | grep -v '^#' >$out
Флаги:
-E
указывает GCC для запуска только препроцессора-x c
указывает GCC обрабатывать ваш скрипт компоновщика как исходный файл C (он необходим для запуска GCC с вашим скриптом LD)
Или вы можете просто использовать инструмент cpp
, который на самом деле является препроцессором C.
После этого вы сможете использовать сгенерированный скрипт компоновщика для сборки вашей программы (например, в Makefile).
Примере
Вот как я решил эту проблему в своем проекте:
Вот мой скрипт компоновщика использует препроцессор ({ Директива {X0}} и константа
CONFIG_TEXT_BASE
). Отрывок:#include <config.h>
Здесь скрипт для создания предварительно обработанный скрипт компоновщика. Отрывок:
gcc -E -x c -Iinclude $cflags $in | grep -v '^#' >>$out
Вот мой
Makefile
, он генерирует предварительно обработанный компоновщик сценарий в целевом объекте$(LDS_GEN)
(строка 53), и этот сгенерированный сценарий используется для построения двоичного файла результата (строка 42). Отрывок:$(LDS_GEN): $(LDS) build/gen-lds.sh $(LDS) $(LDS_GEN) $(CFLAGS) $(APP).bin: $(OBJS) $(LDS_GEN) $(LD) $(OBJS) -T $(LDS_GEN) -o $(APP).elf
Небольшое обновление спустя долгое время. Этот способ предварительной обработки работает до тех пор, пока файл памяти не будет содержать строк, вводящих в заблуждение препроцессор. Например.:
"KEEP(*path/*.o(.rodata .rodata*))"
Символ «/ *» после пути считается началом комментария (строка содержит то, что считается началом многострочного комментария C, а не шаблоном соответствия).
Эта строка действительна для компоновщика, но считается комментарием, и вывод препроцессора C удалит все, пока не будет найден предполагаемый закрывающий комментарий:
"KEEP(*path"
Полученный файл явно недействителен для компоновщика. На данный момент у меня нет решения.
Чтобы упростить ответ Сэма, я добавил следующее в свой make-файл, и мы пошли :)
PRE_LD_FILE = $(PROG_NAME).ld
LD_FILE = $(PROG_NAME)_generated.ld
$(LD_FILE) : $(PRE_LD_FILE)
cpp $(PRE_LD_FILE) | grep -v '^#' >>$(LD_FILE)
Похожие вопросы
Связанные вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.