Почему такие функции, как "_write" в retarget.c не связаны, когда retarget.o заархивирован в статической библиотеке?
Я реализую retarget.c для перенацеливания вывода printf на последовательный порт для отладки, он может быть связан и работает очень хорошо, если моей команде link нравится это:
arm-none-eabi-gcc --specs=nano.specs --specs=nosys.specs -g -mcpu=cortex-m4 -mthumb -fmessage-length=0 -std=c99 -fno-builtin -Wl,--gc-sections -Wl,-Map=main.map -T"$(LINKERFILE)" -o main.elf main.o retarget.o $(BUILDDIR)/libs.a -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
но когда я архивирую retarget.o
в файл архива $(BUILDDIR)/libs.a
и команде link нравится эта:
arm-none-eabi-gcc --specs=nano.specs --specs=nosys.specs -g -mcpu=cortex-m4 -mthumb -fmessage-length=0 -std=c99 -fno-builtin -Wl,--gc-sections -Wl,-Map=main.map -T"$(LINKERFILE)" -o main.elf main.o $(BUILDDIR)/libs.a -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
это может быть успешно связано, но функция printf ничего не выводит на последовательный порт, кажется, что мои собственные функции версии, такие как _write
в retarget.c не используются в окончательной скомпилированной программе.
1 ответ
Потому что уже определено в
libnosys.a
, включено через
Примечание . Следующее расследование было проведено с использованием набора инструментов ARM 9-2019-q4-major, загруженного отсюда .
Это требует элементарных знаний файлов спецификаций (о файлах спецификаций)
Встроенные спецификации компилятора можно увидеть с помощью
arm-none-eabi-gcc -dumpspecs
( gcc -dumpspecs
)
Проходящий
--specs=nosys.specs
в начале командной строки вставляет
-lnosys
в звонке. ( Что такое термины «nosys», «nano», «rdimon» при использовании ARM GCC?)
arm-none-eabi-objdump -t arm-none-eabi/lib/libnosys.a | grep _write
находит
_write(...)
который, вероятно, переопределяет тот, который вы определили в
$(BUILDDIR)/libs.a
Мне тоже любопытно, почему
.a
файлы обрабатываются иначе, чем
.o
файлы при вызове. Почему , кажется, находится в разработке
gcc
а также
ld
и все еще ускользает от меня.
Чтобы использовать
_write
символ, определенный в статической библиотеке
libs.a
вызвать gcc с помощью
-Wl,--undefined=_write
во время окончательной привязки.
(через этот ответ ). Из
man ld
,
--undefined=symbol
принудительно вводит символ в выходной файл как неопределенный символ.
См. Также репозиторий микропрограмм Makani, в котором статическая библиотека, реализующая системные вызовы, помечает их как
--undefined
(Генерация опций компоновщика )