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?

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

16 REPLIES 16
Guillaume K
ST Employee

@pav_ivanovs wrote:

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:

you are creating a #define for the "MCU GCC Assembler". do it in the "MCU GCC compiler" section instead.

pav_ivanovs
Associate II

Ok, I've added the same symbol there, but the result is the same

pav_ivanovs_0-1714117206407.png

Guillaume K
ST Employee

Is there an error reported by compiler ?

I suggest to remove the double quotes. Especially the double quote that is on the second line.

In your C code, how do you use THIS_FILE__ ? I suggest to add a semi colon after THIS_FILE__ on a single line:

 

 

THIS_FILE__;

 

 

Try to find in the CDT build console what command line is really used ( "arm-none-eabi-gcc c:/path/to/file.c -DTHIS_FILE=...")

ok, thanks, adding

THIS_FILE__;

at the top of source files helped, but my initial intention was to automatically add the

static char const thisFile[] = __FILE__;

line at the top of each source file. If I need to manually place THIS_FILE__; at the top of each source file, then it sort of defeats the purpose here. Is there a way to use the Define symbol (-D) feature or smth else to achieve what I want?

That's not how define works. A define creates a symbol that can be used for text substitution or conditional compilation. It's not designed to add code to a file. That's what include is for.

You can define the symbol like this:

unsigned_char_array_1-1714120663850.png

 

The index keeps track of all the symbols in the code, so you can navigate to declarations and definitions of variables and functions. If you change global symbols all files have to be recompiled and this potentially affects the index.

I have a better solution. Use the -include command to force include a file in all source files without modifying the files. You will need to create one header file.

 

unsigned_char_array_0-1714119848430.png

global.h:

 

 

 

 

 

 

#ifndef GLOBAL_H_
#define GLOBAL_H_

#define thisFile __FILE__

#endif // GLOBAL_H_

 

 

 

 

And in my main.c:

 

 

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

 

 

 

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.
pav_ivanovs
Associate II

Thanks for advice, but unfortunately, it doesn't do exactly what I want. My initial purpose of adding the

 

static char const thisFile[] = __FILE__;

 

line at the top of each source file was to create a string that contains the file path only once per source file. The typical issue with debugging using the __FILE__ macro is that it expands to a long path string each time I write

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

and I might have a lot of such calls within a source file. So it basically, clogs up memory pretty quickly. The solution that I'm trying to implement is described here:
https://barrgroup.com/blog/design-contract-embedded-c#endnote2
but it relies on adding

DEFINE_THIS_FILE

macro at the top of each source file, which I would like to automate somehow.


@pav_ivanovs wrote:

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__;

file?


I don't see how a preprocessor definition helps this at all?

Surely, if you can automatically insert a preprocessor definition, then you could just as easily directly insert that line of text?

 


@pav_ivanovs wrote:

it shows this warning, which I don't completely understand.

pav_ivanovs_1-1714114411877.png


This Index is what allows the editor to automatically do cross-referencing, find things referenced via macros, highlight "inactive" condition code, etc, etc.

Obviously, when you change a command-line define, that's going to affect this.

 


@pav_ivanovs wrote:

I might have a lot of such calls within a source file. So it basically, clogs up memory pretty quickly.


No it doesn't. The string gets stored in FLASH only once and referenced multiple times. I just tested it. In memory viewer I see all the constant strings in FLASH and see my file name only once and the address of the string is the same for all function calls in the file. How did you measure your "memory clogging"?

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.

@pav_ivanovs wrote:

 

static char const thisFile[] = __FILE__;

 

 


As @unsigned_char_array said, this creates exactly one instance of the string in memory, and assigns the name thisFile to it.

The macro expansion occurs at this point: thisFile  contains the expansion - not the __FILE__ macro!

 


@pav_ivanovs wrote:

The typical issue with debugging using the __FILE__ macro is that it expands to a long path string each time I write

 

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

 

.


No, it doesn't;  because you are not expanding the macro in that line - you are simply referencing the variable in which it has already been expanded.

 


@pav_ivanovs wrote:

The solution that I'm trying to implement is described here:
https://barrgroup.com/blog/design-contract-embedded-c#endnote2


It isn't described there - it is just mentioned in passing

 

If you're worried about memory usage, then use a file ID instead of the full name - that can then be translated on a less resource-constrained system...