7.10 Reimplementing C library functions

This provides information for building applications without the Arm® standard C library.

To build applications without the Arm standard C library, you must provide an alternative library that reimplements the ISO standard C library functions that your application might need, such as printf(). Your reimplemented library must be compliant with the ARM Embedded Application Binary Interface (AEABI).

To instruct armclang to not use the Arm standard C library, you must use the armclang options -nostdlib and -nostdlibinc. You must also use the --no_scanlib armlink option if you invoke the linker separately.

You must also use the -fno-builtin armclang option to ensure that the compiler does not perform any transformations of built-in functions. Without -fno-builtin, armclang might recognize calls to certain standard C library functions, such as printf(), and replace them with calls to more efficient alternatives in specific cases.

This example reimplements the printf() function to simply return 1 or 0.

//my_lib.c:
int printf(const char *c, ...) 
{
    if(!c)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

Use armclang and armar to create a library from your reimplemented printf() function:

armclang --target=arm-arm-none-eabi -c -O2 -march=armv7-a -mfpu=none mylib.c -o mylib.o
armar --create mylib.a mylib.o

An example application source file foo.c contains:

//foo.c:
extern int printf(const char *c, ...);

void foo(void) 
{
    printf("Hello, world!\n");
}

Use armclang to build the example application source file using the -nostdlib, -nostdlibinc and -fno-builtin options. Then use armlink to link the example reimplemented library using the --no_scanlib option.

armclang --target=arm-arm-none-eabi -c -O2 -march=armv7-a -mfpu=none -nostdlib -nostdlibinc -fno-builtin foo.c -o foo.o
armlink foo.o mylib.a -o image.axf --no_scanlib

If you do not use the -fno-builtin option, then the compiler transforms the printf() function to the puts() function, and the linker generates an error because it cannot find the puts() function in the reimplemented library.

armclang --target=arm-arm-none-eabi -c -O2 -march=armv7-a -mfpu=none -nostdlib -nostdlibinc foo.c -o foo.o
armlink foo.o mylib.a -o image.axf --no_scanlib

Error: L6218E: Undefined symbol puts (referred from foo.o).

Note:

If the linker sees a definition of main(), it automatically creates a reference to a startup symbol called __main. The Arm standard C library defines __main to provide startup code. If you use your own library instead of the Arm standard C library, then you must provide your implementation of __main or change the startup symbol using the linker --startup option.
Non-ConfidentialPDF file icon PDF versionDUI0773J
Copyright © 2014–2017, 2019 Arm Limited or its affiliates. All rights reserved.