How to use external sprintf instead of sprintf in libg with GNU Arm Embedded Toolchain Version 10.3-2021.10?

Acutally not only sprintf, there are some other functions have same issue.

I implement sprintf, sscanf, etc in my source code, but get multiple definition error below while linking:

[build] cmd.exe /C "cd . && arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Ofast -std=gnu11 -Wall -fno-builtin -fno-strict-aliasing -fdata-sections -fms-extensions -ffunction-sections -std=gnu11 -Wall -fno-builtin -fno-strict-aliasing -fdata-sections -fms-extensions -ffunction-sections -fms-extensions -fdiagnostics-color=always -Og -g3 -Wl,--gc-sections -flto --specs=nano.specs    -Wl,-TZ:/vsf.linux/project/cmake/aic8800/linker.ld -Wl,-Map=output.map -mabi=aapcs -march=armv7e-m @CMakeFiles\vsf_linux.rsp -o vsf_linux.elf  && cmd.exe /C "cd /D Z:\vsf.linux\project\cmake\aic8800\build && arm-none-eabi-objcopy -O ihex vsf_linux.elf vsf_linux.hex && arm-none-eabi-objcopy -O binary vsf_linux.elf vsf_linux.bin && cd /D Z:\vsf.linux\project\cmake\aic8800\build && arm-none-eabi-size Z:/vsf.linux/project/cmake/aic8800/build/vsf_linux.elf""
[build] c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libg_nano.a(lib_a-sprintf.o): in function `_sprintf_r':
[build] sprintf.c:(.text._sprintf_r+0x0): multiple definition of `_sprintf_r'; CMakeFiles/vsf_linux.dir/Z_/vsf.linux/application/vsf_main.c.obj:Z:/vsf.linux/application/vsf_main.c:8: first defined here
[build] c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libg_nano.a(lib_a-sprintf.o): in function `sprintf':
[build] sprintf.c:(.text.sprintf+0x0): multiple definition of `sprintf'; CMakeFiles/vsf_linux.dir/Z_/vsf.linux/vsf/source/utilities/language_extension/simple_sprintf.c.obj:Z:/vsf.linux/vsf/source/utilities/language_extension/simple_sprintf.c:324: first defined here
[build] collect2.exe: error: ld returned 1 exit status
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
But some other functions like malloc etc is OK, I can implement these functions in user space, and they will replace the same function in libg_nano.
Parents
  • You simply override them by defining functions with identical functional definition. If they are defined WEAK in the standard library they will be overridden, otherwise they are overridden on a first resolution basis so so long as your implementation is passed to the linker before the library containing the original printf definition is searched, it will override. Moreover .o / .obj files specifically are used in symbol resolution before .a / .lib files, so if your implementation is included in your project source, it will always override.

    But in your platform, if printf() of the original library is not defined with __WEAK property, you may not override it.

    Maybe some useful piece of information from https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes :
    "weak
        The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker. "

Reply
  • You simply override them by defining functions with identical functional definition. If they are defined WEAK in the standard library they will be overridden, otherwise they are overridden on a first resolution basis so so long as your implementation is passed to the linker before the library containing the original printf definition is searched, it will override. Moreover .o / .obj files specifically are used in symbol resolution before .a / .lib files, so if your implementation is included in your project source, it will always override.

    But in your platform, if printf() of the original library is not defined with __WEAK property, you may not override it.

    Maybe some useful piece of information from https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes :
    "weak
        The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker. "

Children
No data