Menu

#2671 wrong command line parsing of preprocessor options

open
nobody
None
other
5
2017-10-15
2017-10-15
No

I found a strange behaviour of SDCC when trying to generate dependency files on compile using the -MMD or the -Wp-MMD command line options of sdcc. (using ubuntu 16.04)

using this minimal source code in directory src/:
src/test.h:

void test(void);

src/test.c:

#include "test.h"
void test(void){}

I would like to comile it into directory obj/ using the object file extention .o:

$ sdcc --version
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.6.9 #9998 (Linux)
published under GNU General Public License (GPL)
$ sdcc -c src/test.c -o obj/test.o; ll obj
total 48
-rw-rw-r-- 1 mmayer mmayer  3761 Okt 15 09:56 test.asm
-rw-rw-r-- 1 mmayer mmayer  8121 Okt 15 09:56 test.lst
-rw-rw-r-- 1 mmayer mmayer  1037 Okt 15 09:56 test.o
-rw-rw-r-- 1 mmayer mmayer 30472 Okt 15 09:56 test.sym

works as expected. Now add the -MMD flag:

$ rm obj/*
$ sdcc -MMD -c src/test.c -o obj/test.o; ll obj
total 52
-rw-rw-r-- 1 mmayer mmayer  3761 Okt 15 09:58 test.asm
-rw-rw-r-- 1 mmayer mmayer    34 Okt 15 09:58 test.d
-rw-rw-r-- 1 mmayer mmayer  8121 Okt 15 09:58 test.lst
-rw-rw-r-- 1 mmayer mmayer  1037 Okt 15 09:58 test.o
-rw-rw-r-- 1 mmayer mmayer 30472 Okt 15 09:58 test.sym
$ cat obj/test.d
obj/test.o: src/test.c src/test.h

Still as expected. Now use -Wp-MMD instead:

$ rm obj/*
$ sdcc -Wp-MMD -c src/test.c -o obj/test.o; ll obj
total 48
-rw-rw-r-- 1 mmayer mmayer  3761 Okt 15 09:59 test.asm
-rw-rw-r-- 1 mmayer mmayer  8121 Okt 15 09:59 test.lst
-rw-rw-r-- 1 mmayer mmayer  1037 Okt 15 09:59 test.o
-rw-rw-r-- 1 mmayer mmayer 30472 Okt 15 09:59 test.sym
$ ll
total 12
drwxrwxr-x 2 mmayer mmayer 4096 Okt 15 09:59 obj
-rw-rw-r-- 1 mmayer mmayer   32 Okt 15 09:59 -obj-ext=.rel
drwxrwxr-x 2 mmayer mmayer 4096 Okt 15 09:39 src
$ cat -- -obj-ext\=.rel 
test.rel: src/test.c src/test.h

Now the dependency file is still generated, but in the current directory instead of obj/ and it references the object file without path and using the standard .rel extention instead of the filename given by the -o option.
The behaviour changes slightly when I add in another parameter following the -Wp-MMD:

$ rm -- -obj-ext\=.rel ; rm obj/*
$ sdcc -Wp-MMD -Dnothing -c src/test.c -o obj/test.o; ll obj
total 48
-rw-rw-r-- 1 mmayer mmayer  3761 Okt 15 10:04 test.asm
-rw-rw-r-- 1 mmayer mmayer  8121 Okt 15 10:04 test.lst
-rw-rw-r-- 1 mmayer mmayer  1037 Okt 15 10:04 test.o
-rw-rw-r-- 1 mmayer mmayer 30472 Okt 15 10:04 test.sym
$ ll
total 12
-rw-rw-r-- 1 mmayer mmayer   32 Okt 15 10:04 -Dnothing
drwxrwxr-x 2 mmayer mmayer 4096 Okt 15 10:04 obj
drwxrwxr-x 2 mmayer mmayer 4096 Okt 15 09:39 src
$ cat -- -Dnothing 
test.rel: src/test.c src/test.h

Command line parsing gone bad?

Discussion

  • Michael Mayer

    Michael Mayer - 2017-10-15

    Further investigation shows that the problem is caused by a diffent handling of the -MMD switch by sdcc depending on its context.

    Using -MMD: sdcc propagates this option to sdcpp and automatically adds a generated file name for the dependency file matching the generated object file:

    $ sdcc --verbose -MMD -c src/test.c -o obj/test.o
    sdcc: Calling preprocessor...
    sdcc: sdcpp -nostdinc -Wall -std=c11 -obj-ext=.rel -MMD obj/test.d -MT obj/test.o -D__SDCC_CHAR_UNSIGNED -D__SDCC_MODEL_SMALL -D__SDCC_FLOAT_REENT -D__SDCC=3_6_9 -D__SDCC_VERSION_MAJOR=3 -D__SDCC_VERSION_MINOR=6 -D__SDCC_VERSION_PATCH=9 -DSDCC=369 -D__SDCC_REVISION=9998 -D__SDCC_mcs51 -D__STDC_NO_COMPLEX__=1 -D__STDC_NO_THREADS__=1 -D__STDC_NO_ATOMICS__=1 -D__STDC_NO_VLA__=1 -D__STDC_ISO_10646__=201409L -D__STDC_UTF_16__=1 -D__STDC_UTF_32__=1 -isystem /usr/local/bin/../share/sdcc/include/mcs51 -isystem /usr/local/share/sdcc/include/mcs51 -isystem /usr/local/bin/../share/sdcc/include -isystem /usr/local/share/sdcc/include  src/test.c 
    sdcc: Generating code...
    sdcc: Calling assembler...
    sdcc: sdas8051 -plosgffw obj/test.o obj/test.asm
    $ ls
    obj  src
    $ ls obj/
    test.asm  test.d  test.lst  test.o  test.sym
    $ cat obj/test.d 
    obj/test.o: src/test.c src/test.h
    

    Using -Wp-MMD: sdcc propagates only this option and does not add a file name for the dependency file. This needs to be done manually by using a second -Wp option for sdcc, otherwise the autogenerated "-obj-ext=.rel" parameter would be mistaken for a filename:

    $ sdcc --verbose  -Wp-MMD -Wpfile.d -c src/test.c -o obj/test.o
    sdcc: Calling preprocessor...
    sdcc: sdcpp -nostdinc -Wall -std=c11 -MMD file.d -obj-ext=.rel -D__SDCC_CHAR_UNSIGNED -D__SDCC_MODEL_SMALL -D__SDCC_FLOAT_REENT -D__SDCC=3_6_9 -D__SDCC_VERSION_MAJOR=3 -D__SDCC_VERSION_MINOR=6 -D__SDCC_VERSION_PATCH=9 -DSDCC=369 -D__SDCC_REVISION=9998 -D__SDCC_mcs51 -D__STDC_NO_COMPLEX__=1 -D__STDC_NO_THREADS__=1 -D__STDC_NO_ATOMICS__=1 -D__STDC_NO_VLA__=1 -D__STDC_ISO_10646__=201409L -D__STDC_UTF_16__=1 -D__STDC_UTF_32__=1 -isystem /usr/local/bin/../share/sdcc/include/mcs51 -isystem /usr/local/share/sdcc/include/mcs51 -isystem /usr/local/bin/../share/sdcc/include -isystem /usr/local/share/sdcc/include  src/test.c 
    sdcc: Generating code...
    sdcc: Calling assembler...
    sdcc: sdas8051 -plosgffw obj/test.o obj/test.asm
    $ ls
    file.d  obj  src
    $ ll obj/
    total 48
    -rw-rw-r-- 1 mmayer mmayer  3761 Okt 15 11:02 test.asm
    -rw-rw-r-- 1 mmayer mmayer  8121 Okt 15 11:02 test.lst
    -rw-rw-r-- 1 mmayer mmayer  1037 Okt 15 11:02 test.o
    -rw-rw-r-- 1 mmayer mmayer 30472 Okt 15 11:02 test.sym
    $ cat file.d 
    test.rel: src/test.c src/test.h
    

    Interestlingly, in this case the standard name "test.rel" is used in the dependency file instead of the correct and full filename "obj/test.o".

     
  • Michael Mayer

    Michael Mayer - 2017-10-15

    This filename mismatch can be taken care of with two more -Wp options: -Wp-MT -Wpobj/test.o as it is done automatically for the simple -MMD case:

    $ sdcc --verbose -Wp-MMD -Wpfile.d -Wp-MT -Wpobj/test.o -c src/test.c -o obj/test.o
    sdcc: Calling preprocessor...
    sdcc: sdcpp -nostdinc -Wall -std=c11 -MMD file.d -MT obj/test.o -obj-ext=.rel -D__SDCC_CHAR_UNSIGNED -D__SDCC_MODEL_SMALL -D__SDCC_FLOAT_REENT -D__SDCC=3_6_9 -D__SDCC_VERSION_MAJOR=3 -D__SDCC_VERSION_MINOR=6 -D__SDCC_VERSION_PATCH=9 -DSDCC=369 -D__SDCC_REVISION=9998 -D__SDCC_mcs51 -D__STDC_NO_COMPLEX__=1 -D__STDC_NO_THREADS__=1 -D__STDC_NO_ATOMICS__=1 -D__STDC_NO_VLA__=1 -D__STDC_ISO_10646__=201409L -D__STDC_UTF_16__=1 -D__STDC_UTF_32__=1 -isystem /usr/local/bin/../share/sdcc/include/mcs51 -isystem /usr/local/share/sdcc/include/mcs51 -isystem /usr/local/bin/../share/sdcc/include -isystem /usr/local/share/sdcc/include  src/test.c 
    sdcc: Generating code...
    sdcc: Calling assembler...
    sdcc: sdas8051 -plosgffw obj/test.o obj/test.asm
    $ ls
    file.d  obj  src
    $ cat file.d
    obj/test.o: src/test.c src/test.h
    

    So this is more a lack of detailed documentation than a software bug. It would be helpful to illustrate the difference of these two invocations by explaining in more detail what -MMD really does: Propagating -MMD to sdcpp plus generating two sensible filenames.

     

Log in to post a comment.

Monday.com Logo