cancel
Showing results for 
Search instead for 
Did you mean: 

Use of Define symbols (-D) with the semicolon ";" sign in STM32CubeIDE

pav_ivanovs
Associate II

Hi,

I want to automatically add the following line of code at the top of each source file within my project:

static char const thisFile[] = __FILE__;

For this, I'm creating the following Define symbol (-D) in STM32CubeIDE, by going to project Properties -> C/C++ Build -> Settings -> Tool Settings -> MCU GCC Assembler -> Preprocessor:

pav_ivanovs_1-1714115156456.png

However, when I click on OK -> Apply and Close, it shows this warning, which I don't completely understand.

pav_ivanovs_1-1714114411877.png

Anyway, I click Rebuild Index, and it changes my symbol by removing the semicolon at the end and adding some new double quote symbol "

pav_ivanovs_2-1714115197413.png

and, when I build the project after this (the code already uses thisFile string in its functions), it throws this error:
error: 'thisFile' undeclared (first use in this function)

I suspect, that it happens because the preprocessor can't properly transform the semicolon from my symbol, so the whole static char const thisFile[] = __FILE__ line becomes invalid.


Is there a way how to make this Define symbol (-D) feature to work with semicolons or maybe some other way how to add my desired line of code at the top of each source file?

16 REPLIES 16

 

__FILE_NAME__

 

Takes less space then __FILE__. It doesn't have the full path only filename and extension. It is not standard, but it works in GCC.

The compiler is smart enough not to create duplicates of strings in FLASH so even if you use string literals in different places in one file it won't be duplicated. Unless you concatenate the strings, because those are seen as new ones. Strings are passed by address, not by copy.

You can use the -E parameter to get the intermediate files (main.o becomes a readable text file, for instance). It will result in compiler errors, but you can see what the preprocessor outputs. You can see that __FILE_NAME__ gets expanded to "main.c" and the compiler will store that in 1 place in FLASH.

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.

@unsigned_char_array wrote:

global.h:

 

#ifndef GLOBAL_H_
#define GLOBAL_H_

#define thisFile __FILE__

#endif // GLOBAL_H_

 

 

And in my main.c:

 

SerialDebug("%s\r\n", thisFile);

 


But that would be equivalent to writing

 

SerialDebug( "%s\r\n", __FILE__ );

 

which would, indeed, cause the __FILE__ macro to be expanded each time it is used.

Surely, what you really want is:

 

#ifndef GLOBAL_H_
#define GLOBAL_H_

static char thisFile[] = __FILE__;

#endif // GLOBAL_H_

 

so that you create one variable per file, where the macro is expanded.

 

and then .c files can do

 

SerialDebug( "%s\r\n", thisFile );

 

to just reference the file-local variable without re-expanding the __FILE__  macro

 


@unsigned_char_array wrote:

The compiler is smart enough not to create duplicates of strings in FLASH so even if you use string literals in different places in one file it won't be duplicated.


This is controlled by the -fmerge-constants option:

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#:~:text=%2Dfmerge%2Dconstants%20%C2%B6,%2DOs.

 

EDIT:

The link highlighting doesn't seem to have worked there. :frowning_face:

Try this :https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fmerge-constants

 

and note that there's also a -fmerge-all-constants - with some caveats ...


@Andrew Neil wrote:

Surely, what you really want is:

 

 

#ifndef GLOBAL_H_
#define GLOBAL_H_

static char thisFile[] = __FILE__;

#endif // GLOBAL_H_

 

 


Yes, but in that case it expands to "path/global.h" and not to "path/main.c".

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.

Of course!

<facepalm>

I've solved it.

Modify build command in STM32CubeIDE:

from:

 

${COMMAND} ${INPUTS} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}

 

to:

 

${COMMAND} ${INPUTS} -D__CFILE__='${INPUTS}' ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}

 

for the equivalent of __FILE__

or even better:

 

${COMMAND} ${INPUTS} -D__CFILE__='"${InputFileName}"' ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}

 

for the equivalent of __FILE_NAME__

or

${COMMAND} ${INPUTS} -D__CFILE__='"${InputFileBaseName}"' ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT}

for the equivalent of __BASE_FILE__

Inside a header file the macro __CFILE__ will have not expand to the path of the header file being processed, but to the path to the C file that includes the header file.

Combine this with with -include global.h in misc and with global.h containing:

 

static char thisFile[] = __CFILE__;

 

Now it works. This does not work with __FILE__ or __FILE_NAME__ as those will expand to the path or name of the header file.

Like I wrote before it is not going to save memory in any way (please measure memory use by checking build analysis and map file and check where all string literals are stored to verify).

(I also found a way to define the project name, can also be useful: -DPROJECT_NAME='"${ProjName}"')

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.