Почему такие функции, как "_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(Генерация опций компоновщика )

Другие вопросы по тегам