Menu

PIC16 Port error: Non-existent external symbol - "_sprintf"

Help
CScotty
2017-04-17
2017-04-17
  • CScotty

    CScotty - 2017-04-17

    It appears thay the I am missing or can't find the library containing the printing functions documented in the 3.6.0 manual in section 4.6.18.2.

    I have inclued the headers stdio.h and string.h and am targeting an PCI18F device. What else might I be missing?

    Best,
    N

     

    Last edit: CScotty 2017-04-17
  • Diego Herranz

    Diego Herranz - 2017-04-17

    Hi,

    Can you provide a minimum example so we can try to reproduce the error?

    Diego

     
  • CScotty

    CScotty - 2017-04-17

    Of course:

    Added square brackets around hashes to stop silly formatting..

    #pragma config XINST=OFF
    #include <pic18fregs.h>
    #include <stdio.h>
    #include <string.h>
    
    void main(void) {
        char buf[100];
    
        while(1) {
            sprintf(buf,"Hello World!");
            LATBbits.LATB0=1;
        }   
    }
    
    "C:\Program Files\SDCC\bin\SDCC.exe" --use-non-free -c -mpic16 -p18f26k22 main.c  -obuild/default/production/main.o
    gnumkdir -p dist/default/production 
    "C:\Program Files\SDCC\bin\SDCC.exe" -Wl-c -Wl-m --use-non-free -mpic16 -p18f26k22 build/default/production/main.o -odist/default/production/test.X.production.hex 
    message: Using default linker script "C:\Program Files (x86)\gputils\lkr\18f26k22_g.lkr".
    error: Non-existent external symbol - "_sprintf" - used in "S_main__main" section.
    

    Best,
    N

     

    Last edit: Raphael Neider 2017-04-17
  • Raphael Neider

    Raphael Neider - 2017-04-17

    You may need to manually link with libc18f to get the implementation of the requested functions.

     
  • CScotty

    CScotty - 2017-04-17

    Explicitly adding libc18f.lib did not change anything. But thanks for the suggestion.

    Best.
    N

     
  • Diego Herranz

    Diego Herranz - 2017-04-17

    I've just seen Raphael has replied. A slightly longer answer :)

    I use linux so some paths and commands are slightly different, but it should be very similar.

    $ sdcc --version
    SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.6.0 #9615 (Linux)
    

    It seems you're using MPLAB X which is calling SDCC to compile first, and then a second time to link and produce the HEX file.

    Reproducing those two steps.

    Compilation:
    $ sdcc --use-non-free -c -mpic16 -p18f26k22 main.c -omain.o
    All OK

    Linkage and HEX generation:

    $ sdcc -Wl-c -Wl-m --use-non-free -mpic16 -p18f26k22 main.o -otest.hex message: Using default linker script "/usr/local/share/gputils/lkr/18f26k22_g.lkr".
    error: Missing definition for symbol "_sprintf", required by "main.o".
    

    I get the same error as you do.

    However, calling SDCC in just one command works OK (when SDCC gets called as a single command, it compiles, links and generates the HEX file):

    $ sdcc --use-non-free -mpic16 -p18f26k22 main.c
    

    Let's see which libraries it is liking against (by using verbose) when doing everything in one step vs separate linkage call:

    Single step:

    $ sdcc --use-non-free -mpic16 -p18f26k22 main.c -V
    [...]
    + /usr/local/bin/gplink -I/usr/local/bin/../share/sdcc/lib/pic16 -I/usr/local/share/sdcc/lib/pic16 -I/usr/local/bin/../share/sdcc/non-free/lib/pic16 -I/usr/local/share/sdcc/non-free/lib/pic16   -w -r -o main main.o  crt0iz.o libdev18f26k22.lib libsdcc.lib libc18f.lib 
    

    Separate linkage call:

    $ sdcc -Wl-c -Wl-m --use-non-free -mpic16 -p18f26k22 main.o  -otest.hex -V
    + /usr/local/bin/gplink -I/usr/local/bin/../share/sdcc/lib/pic16 -I/usr/local/share/sdcc/lib/pic16 -I/usr/local/bin/../share/sdcc/non-free/lib/pic16 -I/usr/local/share/sdcc/non-free/lib/pic16  -c -m  -w -r -o test.hex  main.o  crt0iz.o libdev18f26k22.lib libsdcc.lib 
    message: Using default linker script "/usr/local/share/gputils/lkr/18f26k22_g.lkr".
    error: Missing definition for symbol "_sprintf", required by "main.o".
    

    You can see that the missing library is libc18f.lib as Raphael just mentioned.

    If you add that library manually at the link stage, it works:

    $ sdcc -Wl-c -Wl-m --use-non-free -mpic16 -p18f26k22 main.o libc18f.lib -otest.hex
    

    You may need to add libc18f.lib somewhere in MPLAB's SDCC config.

     
  • CScotty

    CScotty - 2017-04-17

    HI Diego,

    Your point is well made, thanks.

    I have tried explicity adding the c library to MPLAB the configuration and that did not help. I notice the comand line did not change either.

    I see there is a library pragma too...

    #pramga library module
    

    I tried

    #pragma library c
    and
    #pragma library libc18f.lib
    

    no luck with that either. I feel I can't be the first person to try this ;)

    I guess my fallback will be to compile outside of MPLAB but that would be a real shame as I have already put a fair amount of effort into being able to easily switch between SDCC and XC8 compilers just by selecting a different configuration.

    EDIT:

    If I modify the default linker script by adding

    FILES "C:\Program Files\SDCC\lib\pic16\libc18f.lib"
    

    i cna make it work. It just feels rather kludgey. There has to be a better way.

    Best,
    N

     

    Last edit: CScotty 2017-04-17

Log in to post a comment.