Почему такие функции, как _write в retarget.c, не связаны, когда retarget.o заархивирован в статической библиотеке?

Я реализую retarget.c, чтобы перенаправить вывод printf на последовательный порт для отладки, он может быть связан и работает очень хорошо, если моей команде ссылки нравится это:

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, и команде ссылки нравится этот:

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, не используются в окончательной скомпилированной программе.


person xingkong    schedule 25.01.2016    source источник
comment
Что такое $(LIBSFILE)? Я думаю, вы должны преобразовать свой скомпилированный код в статическую или динамическую библиотеку, чтобы делать то, что вы хотите.   -  person LPs    schedule 25.01.2016
comment
Попробуйте связать свою статическую библиотеку до или после libc и посмотрите, изменит ли это ситуацию. Я не помню правил, по которым выбираются объекты и символы, но порядок аргументов командной строки для gcc (который вы, кажется, используете) определенно имеет значение.   -  person Art    schedule 25.01.2016
comment
@LPs @Art Спасибо за ваши ответы, я обновил свои вопросы и заменил некоторые макросы реальными аргументами. @Art, позже я удалил -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group в командной строке, затем команду ссылки, например: 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, но результат все тот же, функция printf ничего не выводит на последовательный порт   -  person xingkong    schedule 27.01.2016
comment
Вы пытались связать свою библиотеку с опцией -l?   -  person LPs    schedule 27.01.2016
comment
@LP, да, в любом случае, я считаю, что nosys.specs сначала была связана другая библиотека. Кажется, я нашел ответ где-то еще, вот ссылка: sourceware.org/ml/ новая библиотека/2006/msg00036.html   -  person xingkong    schedule 31.01.2016


Ответы (1)


Поскольку _write уже определено в libnosys.a, включено через --specs=nosys.specs

Примечание. Следующее исследование было проведено с набором инструментов ARM 9-2019-q4-major, загруженным с сайта здесь.

Для этого требуется элементарное знание файлов спецификаций (О файлах спецификаций)

Встроенные спецификации компилятора можно увидеть с помощью arm-none-eabi-gcc -dumpspecs (gcc -dumpspecs)

Передача --specs=nosys.specs в начале командной строки вставляет -lnosys в вызов ld. (Что такое "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. почему, кажется, заключается в дизайне gcc и ld и до сих пор ускользает от меня.

Чтобы использовать символ _write, определенный в статической библиотеке libs.a

вызовите gcc с -Wl,--undefined=_write во время окончательной компоновки.
(через этот ответ). Из man ld, --undefined=symbol принудительно вводит символ в выходной файл как неопределенный символ.

См. также репозиторий прошивки Makani, в котором статическая библиотека реализует системные вызовы помечает их как --undefined (генерация параметры компоновщика)

person RemarkableBucket    schedule 06.07.2021