2024-04-26 12:12 AM
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:
However, when I click on OK -> Apply and Close, it shows this warning, which I don't completely understand.
Anyway, I click Rebuild Index, and it changes my symbol by removing the semicolon at the end and adding some new double quote symbol "
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?
Solved! Go to Solution.
2024-04-26 07:02 AM - edited 2024-04-29 01:25 AM
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}"')
2024-04-26 12:33 AM
@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.
2024-04-26 12:40 AM
Ok, I've added the same symbol there, but the result is the same
2024-04-26 12:49 AM - edited 2024-04-26 12:58 AM
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=...")
2024-04-26 01:00 AM
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?
2024-04-26 01:19 AM - edited 2024-04-26 01:38 AM
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:
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.
global.h:
#ifndef GLOBAL_H_
#define GLOBAL_H_
#define thisFile __FILE__
#endif // GLOBAL_H_
And in my main.c:
SerialDebug("%s\r\n", thisFile);
2024-04-26 02:25 AM
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.
2024-04-26 02:39 AM
@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.
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.
2024-04-26 02:40 AM
@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"?
2024-04-26 02:55 AM
@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...